Пример #1
0
void RenderFlowThread::computeOverflowStateForRegions(LayoutUnit oldClientAfterEdge)
{
    LayoutUnit height = oldClientAfterEdge;
    // FIXME: the visual overflow of middle region (if it is the last one to contain any content in a render flow thread)
    // might not be taken into account because the render flow thread height is greater that that regions height + its visual overflow
    // because of how computeLogicalHeight is implemented for RenderFlowThread (as a sum of all regions height).
    // This means that the middle region will be marked as fit (even if it has visual overflow flowing into the next region)
    if (hasRenderOverflow() && ( (isHorizontalWritingMode() && visualOverflowRect().maxY() > clientBoxRect().maxY()) 
                                || (!isHorizontalWritingMode() && visualOverflowRect().maxX() > clientBoxRect().maxX())))
        height = isHorizontalWritingMode() ? visualOverflowRect().maxY() : visualOverflowRect().maxX();

    RenderRegion* lastReg = lastRegion();
    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
        RenderRegion* region = *iter;
        if (!region->isValid()) {
            region->setRegionState(RenderRegion::RegionUndefined);
            continue;
        }
        LayoutUnit flowMin = height - (isHorizontalWritingMode() ? region->flowThreadPortionRect().y() : region->flowThreadPortionRect().x());
        LayoutUnit flowMax = height - (isHorizontalWritingMode() ? region->flowThreadPortionRect().maxY() : region->flowThreadPortionRect().maxX());
        RenderRegion::RegionState previousState = region->regionState();
        RenderRegion::RegionState state = RenderRegion::RegionFit;
        if (flowMin <= 0)
            state = RenderRegion::RegionEmpty;
        if (flowMax > 0 && region == lastReg)
            state = RenderRegion::RegionOverset;
        region->setRegionState(state);
        // determine whether the NamedFlow object should dispatch a regionLayoutUpdate event
        // FIXME: currently it cannot determine whether a region whose regionOverset state remained either "fit" or "overset" has actually
        // changed, so it just assumes that the NamedFlow should dispatch the event
        if (previousState != state
            || state == RenderRegion::RegionFit
            || state == RenderRegion::RegionOverset)
            setDispatchRegionLayoutUpdateEvent(true);
    }

    // With the regions overflow state computed we can also set the overset flag for the named flow.
    // If there are no valid regions in the chain, overset is true.
    m_overset = lastReg ? lastReg->regionState() == RenderRegion::RegionOverset : true;
}
Пример #2
0
int GModel::writeKEY(const std::string &name, int saveAll,
                     int saveGroupsOfNodes, 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 = 0x51;

  indexMeshVertices(saveAll & 0x51);
  std::vector<GEntity *> entities;
  getEntities(entities);

  fprintf(fp, "$# LS-DYNA Keyword file created by Gmsh\n*KEYWORD\n*TITLE\n");
  fprintf(fp, " %s\n", name.c_str());

  fprintf(fp, "*NODE\n");
  for(std::size_t i = 0; i < entities.size(); i++)
    for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
      entities[i]->mesh_vertices[j]->writeKEY(fp, scalingFactor);

  if(!(saveAll & 0x2)) // save or ignore Vertex, not in GUI
    for(viter it = firstVertex(); it != lastVertex(); ++it) {
      writeElementsKEY(fp, *it, (*it)->points, saveAll & 0x1);
    }
  if(!(saveAll & 0x8)) // save or ignore line
    for(eiter it = firstEdge(); it != lastEdge(); ++it) {
      writeElementsKEY(fp, *it, (*it)->lines, saveAll & 0x4);
    }
  if(!(saveAll & 0x20)) // save or ignore surface
    for(fiter it = firstFace(); it != lastFace(); ++it) {
      writeElementsKEY(fp, *it, (*it)->triangles, saveAll & 0x10);
      writeElementsKEY(fp, *it, (*it)->quadrangles, saveAll & 0x10);
    }
  if(!(saveAll & 0x80)) // save or ignore surface
    for(riter it = firstRegion(); it != lastRegion(); ++it) {
      writeElementsKEY(fp, *it, (*it)->tetrahedra, saveAll & 0x40);
      writeElementsKEY(fp, *it, (*it)->hexahedra, saveAll & 0x40);
      writeElementsKEY(fp, *it, (*it)->prisms, saveAll & 0x40);
      writeElementsKEY(fp, *it, (*it)->pyramids, saveAll & 0x40);
    }

  std::map<int, std::vector<GEntity *> > groups[4];
  getPhysicalGroups(groups);

  int setid = 0;
  // save elements sets for each physical group
  if(saveGroupsOfNodes & 0x2) {
    for(int dim = 0; dim <= 3; dim++) {
      if(saveAll & (0x2 << (2 * dim))) continue; // elements are ignored
      for(std::map<int, std::vector<GEntity *> >::iterator it =
            groups[dim].begin();
          it != groups[dim].end(); it++) {
        std::vector<GEntity *> &entities = it->second;
        int n = 0;
        for(std::size_t i = 0; i < entities.size(); i++) {
          for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
            MElement *e = entities[i]->getMeshElement(j);
            if(!n) {
              const char *str = (e->getDim() == 3) ?
                                  "SOLID" :
                                  (e->getDim() == 2) ?
                                  "SHELL" :
                                  (e->getDim() == 1) ? "BEAM" : "NODE";
              fprintf(fp, "*SET_%s_LIST\n$# %s\n%d", str,
                      physicalName(this, dim, it->first).c_str(), ++setid);
            }
            if(!(n % 8))
              fprintf(fp, "\n%lu", e->getNum());
            else
              fprintf(fp, ", %lu", e->getNum());
            n++;
          }
        }
        if(n) fprintf(fp, "\n");
      }
    }
  }

  // save node sets for each physical group, for easier load/b.c.
  if(saveGroupsOfNodes & 0x1) {
    for(int dim = 1; dim <= 3; dim++) {
      for(std::map<int, std::vector<GEntity *> >::iterator it =
            groups[dim].begin();
          it != groups[dim].end(); it++) {
        std::set<MVertex *> nodes;
        std::vector<GEntity *> &entities = it->second;
        for(std::size_t i = 0; i < entities.size(); i++) {
          for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
            MElement *e = entities[i]->getMeshElement(j);
            for(std::size_t k = 0; k < e->getNumVertices(); k++)
              nodes.insert(e->getVertex(k));
          }
        }
        fprintf(fp, "*SET_NODE_LIST\n$# %s\n%d",
                physicalName(this, dim, it->first).c_str(), ++setid);
        int n = 0;
        for(std::set<MVertex *>::iterator it2 = nodes.begin();
            it2 != nodes.end(); it2++) {
          if(!(n % 8))
            fprintf(fp, "\n%ld", (*it2)->getIndex());
          else
            fprintf(fp, ", %ld", (*it2)->getIndex());
          n++;
        }
        if(n) fprintf(fp, "\n");
      }
    }
  }

  fprintf(fp, "*END\n");
  fclose(fp);
  return 1;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
0
void RenderFlowThread::layout()
{
    StackStats::LayoutCheckPoint layoutCheckPoint;

    m_pageLogicalHeightChanged = m_regionsInvalidated && everHadLayout();
    if (m_regionsInvalidated) {
        m_regionsInvalidated = false;
        m_regionsHaveUniformLogicalWidth = true;
        m_regionsHaveUniformLogicalHeight = true;
        m_regionRangeMap.clear();
        m_breakBeforeToRegionMap.clear();
        m_breakAfterToRegionMap.clear();

        LayoutUnit previousRegionLogicalWidth = 0;
        LayoutUnit previousRegionLogicalHeight = 0;
        bool firstRegionVisited = false;
        if (hasRegions()) {
            for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
                RenderRegion* region = *iter;
                ASSERT(!region->needsLayout());
                
                region->deleteAllRenderBoxRegionInfo();

                // In the normal layout phase we need to initialize the overrideLogicalContentHeight for auto-height regions.
                // See initializeRegionsOverrideLogicalContentHeight for the explanation.
                // Also, if we have auto-height regions we can't assume m_regionsHaveUniformLogicalHeight to be true in the first phase
                // because the auto-height regions don't have their height computed yet.
                if (view()->normalLayoutPhase() && region->hasAutoLogicalHeight()) {
                    region->setOverrideLogicalContentHeight(region->maxPageLogicalHeight());
                    m_regionsHaveUniformLogicalHeight = false;
                }

                LayoutUnit regionLogicalWidth = region->pageLogicalWidth();
                LayoutUnit regionLogicalHeight = region->pageLogicalHeight();

                if (!firstRegionVisited)
                    firstRegionVisited = true;
                else {
                    if (m_regionsHaveUniformLogicalWidth && previousRegionLogicalWidth != regionLogicalWidth)
                        m_regionsHaveUniformLogicalWidth = false;
                    if (m_regionsHaveUniformLogicalHeight && previousRegionLogicalHeight != regionLogicalHeight)
                        m_regionsHaveUniformLogicalHeight = false;
                }

                previousRegionLogicalWidth = regionLogicalWidth;
            }
            
            updateLogicalWidth(); // Called to get the maximum logical width for the region.
            updateRegionsFlowThreadPortionRect();
        }
    }

    CurrentRenderFlowThreadMaintainer currentFlowThreadSetter(this);
    RenderBlock::layout();

    m_pageLogicalHeightChanged = false;

    if (lastRegion())
        lastRegion()->expandToEncompassFlowThreadContentsIfNeeded();

    if (shouldDispatchRegionLayoutUpdateEvent())
        dispatchRegionLayoutUpdateEvent();
}
Пример #6
0
int GModel::writeMESH(const std::string &name, int elementTagType,
                      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;

  int numVertices = indexMeshVertices(saveAll);

  fprintf(fp, " MeshVersionFormatted 2\n");
  fprintf(fp, " Dimension\n");
  fprintf(fp, " 3\n");

  fprintf(fp, " Vertices\n");
  fprintf(fp, " %d\n", numVertices);
  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++)
      entities[i]->mesh_vertices[j]->writeMESH(fp, scalingFactor);

  int numEdges = 0, numTriangles = 0, numQuadrangles = 0;
  int numTetrahedra = 0, numHexahedra = 0;
  for(eiter it = firstEdge(); it != lastEdge(); ++it){
    if(saveAll || (*it)->physicals.size()){
      numEdges += (*it)->lines.size();
    }
  }
  for(fiter it = firstFace(); it != lastFace(); ++it){
    if(saveAll || (*it)->physicals.size()){
      numTriangles += (*it)->triangles.size();
      numQuadrangles += (*it)->quadrangles.size();
    }
  }
  for(riter it = firstRegion(); it != lastRegion(); ++it){
    if(saveAll || (*it)->physicals.size()){
      numTetrahedra += (*it)->tetrahedra.size();
      numHexahedra += (*it)->hexahedra.size();
    }
  }

  if(numEdges){
    if(CTX::instance()->mesh.order == 2)
      fprintf(fp, " EdgesP2\n");
    else
      fprintf(fp, " Edges\n");
    fprintf(fp, " %d\n", numEdges);
    for(eiter it = firstEdge(); it != lastEdge(); ++it){
      int numPhys = (*it)->physicals.size();
      if(saveAll || numPhys){
        for(unsigned int i = 0; i < (*it)->lines.size(); i++)
          (*it)->lines[i]->writeMESH(fp, elementTagType, (*it)->tag(),
                                     numPhys ? (*it)->physicals[0] : 0);
      }
    }
  }
  if(numTriangles){
    if(CTX::instance()->mesh.order == 2)
      fprintf(fp, " TrianglesP2\n");
    else
      fprintf(fp, " Triangles\n");
    fprintf(fp, " %d\n", numTriangles);
    for(fiter it = firstFace(); it != lastFace(); ++it){
      int numPhys = (*it)->physicals.size();
      if(saveAll || numPhys){
        for(unsigned int i = 0; i < (*it)->triangles.size(); i++)
          (*it)->triangles[i]->writeMESH(fp, elementTagType, (*it)->tag(),
                                         numPhys ? (*it)->physicals[0] : 0);
      }
    }
  }
  if(numQuadrangles){
    fprintf(fp, " Quadrilaterals\n");
    fprintf(fp, " %d\n", numQuadrangles);
    for(fiter it = firstFace(); it != lastFace(); ++it){
      int numPhys = (*it)->physicals.size();
      if(saveAll || numPhys){
        for(unsigned int i = 0; i < (*it)->quadrangles.size(); i++)
          (*it)->quadrangles[i]->writeMESH(fp, elementTagType, (*it)->tag(),
                                           numPhys ? (*it)->physicals[0] : 0);
      }
    }
  }
  if(numTetrahedra){
    if(CTX::instance()->mesh.order == 2)
      fprintf(fp, " TetrahedraP2\n");
    else
      fprintf(fp, " Tetrahedra\n");
    fprintf(fp, " %d\n", numTetrahedra);
    for(riter it = firstRegion(); it != lastRegion(); ++it){
      int numPhys = (*it)->physicals.size();
      if(saveAll || numPhys){
        for(unsigned int i = 0; i < (*it)->tetrahedra.size(); i++)
          (*it)->tetrahedra[i]->writeMESH(fp, elementTagType, (*it)->tag(),
                                          numPhys ? (*it)->physicals[0] : 0);
      }
    }
  }
  if(numHexahedra){
    fprintf(fp, " Hexahedra\n");
    fprintf(fp, " %d\n", numHexahedra);
    for(riter it = firstRegion(); it != lastRegion(); ++it){
      int numPhys = (*it)->physicals.size();
      if(saveAll || numPhys){
        for(unsigned int i = 0; i < (*it)->hexahedra.size(); i++)
          (*it)->hexahedra[i]->writeMESH(fp, elementTagType, (*it)->tag(),
                                         numPhys ? (*it)->physicals[0] : 0);
      }
    }
  }

  fprintf(fp, " End\n");

  fclose(fp);
  return 1;
}
Пример #7
0
void RenderFlowThread::layout()
{
    m_pageLogicalHeightChanged = m_regionsInvalidated && everHadLayout();
    if (m_regionsInvalidated) {
        m_regionsInvalidated = false;
        m_hasValidRegions = false;
        m_regionsHaveUniformLogicalWidth = true;
        m_regionsHaveUniformLogicalHeight = true;
        m_regionRangeMap.clear();
        LayoutUnit previousRegionLogicalWidth = 0;
        LayoutUnit previousRegionLogicalHeight = 0;
        if (hasRegions()) {
            for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
                RenderRegion* region = *iter;
                if (!region->isValid())
                    continue;
                ASSERT(!region->needsLayout());
                
                region->deleteAllRenderBoxRegionInfo();

                LayoutUnit regionLogicalWidth = region->pageLogicalWidth();
                LayoutUnit regionLogicalHeight = region->pageLogicalHeight();

                if (!m_hasValidRegions)
                    m_hasValidRegions = true;
                else {
                    if (m_regionsHaveUniformLogicalWidth && previousRegionLogicalWidth != regionLogicalWidth)
                        m_regionsHaveUniformLogicalWidth = false;
                    if (m_regionsHaveUniformLogicalHeight && previousRegionLogicalHeight != regionLogicalHeight)
                        m_regionsHaveUniformLogicalHeight = false;
                }

                previousRegionLogicalWidth = regionLogicalWidth;
            }
            
            updateLogicalWidth(); // Called to get the maximum logical width for the region.
            
            LayoutUnit logicalHeight = 0;
            for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
                RenderRegion* region = *iter;
                if (!region->isValid())
                    continue;
                    
                LayoutUnit regionLogicalWidth = region->pageLogicalWidth();
                LayoutUnit regionLogicalHeight = region->logicalHeightOfAllFlowThreadContent();
    
                LayoutRect regionRect(style()->direction() == LTR ? ZERO_LAYOUT_UNIT : logicalWidth() - regionLogicalWidth, logicalHeight, regionLogicalWidth, regionLogicalHeight);
                region->setFlowThreadPortionRect(isHorizontalWritingMode() ? regionRect : regionRect.transposedRect());
                logicalHeight += regionLogicalHeight;
            }
        }
    }

    CurrentRenderFlowThreadMaintainer currentFlowThreadSetter(this);
    RenderBlock::layout();

    m_pageLogicalHeightChanged = false;

    if (lastRegion())
        lastRegion()->expandToEncompassFlowThreadContentsIfNeeded();

    if (shouldDispatchRegionLayoutUpdateEvent())
        dispatchRegionLayoutUpdateEvent();
}
Пример #8
0
int GModel::readMED(const std::string &name)
{
  med_idt fid = MEDouvrir((char*)name.c_str(), MED_LECTURE);
  if(fid < 0) {
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  med_int v[3], vf[3];
  MEDversionDonner(&v[0], &v[1], &v[2]);
  MEDversionLire(fid, &vf[0], &vf[1], &vf[2]);
  Msg::Info("Reading MED file V%d.%d.%d using MED library V%d.%d.%d",
            vf[0], vf[1], vf[2], v[0], v[1], v[2]);
  if(vf[0] < 2 || (vf[0] == 2 && vf[1] < 2)){
    Msg::Error("Cannot read MED file older than V2.2");
    return 0;
  }

  std::vector<std::string> meshNames;
  for(int i = 0; i < MEDnMaa(fid); i++){
    char meshName[MED_TAILLE_NOM + 1], meshDesc[MED_TAILLE_DESC + 1];
    med_int spaceDim;
    med_maillage meshType;
#if (MED_MAJOR_NUM == 3)
    med_int meshDim, nStep;
    char dtUnit[MED_SNAME_SIZE + 1];
    char axisName[3 * MED_SNAME_SIZE + 1], axisUnit[3 * MED_SNAME_SIZE + 1];
    med_sorting_type sortingType;
    med_axis_type axisType;
    if(MEDmeshInfo(fid, i + 1, meshName, &spaceDim, &meshDim, &meshType, meshDesc,
                   dtUnit, &sortingType, &nStep, &axisType, axisName, axisUnit) < 0){
#else
    if(MEDmaaInfo(fid, i + 1, meshName, &spaceDim, &meshType, meshDesc) < 0){
#endif
      Msg::Error("Unable to read mesh information");
      return 0;
    }
    meshNames.push_back(meshName);
  }

  if(MEDfermer(fid) < 0){
    Msg::Error("Unable to close file '%s'", (char*)name.c_str());
    return 0;
  }

  int ret = 1;
  for(unsigned int i = 0; i < meshNames.size(); i++){
    // we use the filename as a kind of "partition" indicator, allowing to
    // complete a model part by part (used e.g. in DDM, since MED does not store
    // a partition index)
    GModel *m = findByName(meshNames[i], name);
    if(!m) m = new GModel(meshNames[i]);
    ret = m->readMED(name, i);
    if(!ret) return 0;
  }
  return ret;
}

int GModel::readMED(const std::string &name, int meshIndex)
{
  med_idt fid = MEDouvrir((char*)name.c_str(), MED_LECTURE);
  if(fid < 0){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  int numMeshes = MEDnMaa(fid);
  if(meshIndex >= numMeshes){
    Msg::Info("Could not find mesh %d in MED file", meshIndex);
    return 0;
  }

  checkPointMaxNumbers();
  GModel::setCurrent(this); // make sure we increment max nums in this model

  // read mesh info
  char meshName[MED_TAILLE_NOM + 1], meshDesc[MED_TAILLE_DESC + 1];
  med_int spaceDim, nStep = 1;
  med_maillage meshType;
#if (MED_MAJOR_NUM == 3)
  med_int meshDim;
  char dtUnit[MED_SNAME_SIZE + 1];
  char axisName[3 * MED_SNAME_SIZE + 1], axisUnit[3 * MED_SNAME_SIZE + 1];
  med_sorting_type sortingType;
  med_axis_type axisType;
  if(MEDmeshInfo(fid, meshIndex + 1, meshName, &spaceDim, &meshDim, &meshType, meshDesc,
                 dtUnit, &sortingType, &nStep, &axisType, axisName, axisUnit) < 0){
#else
  if(MEDmaaInfo(fid, meshIndex + 1, meshName, &spaceDim, &meshType, meshDesc) < 0){
#endif
    Msg::Error("Unable to read mesh information");
    return 0;
  }

  // FIXME: we should support multi-step MED3 meshes (probably by
  // storing each mesh as a separate model, with a naming convention
  // e.g. meshName_step%d). This way we could also handle multi-mesh
  // time sequences in MED3.
  if(nStep > 1)
    Msg::Warning("Discarding %d last meshes in multi-step MED mesh", nStep - 1);

  setName(meshName);
  setFileName(name);
  if(meshType == MED_NON_STRUCTURE){
    Msg::Info("Reading %d-D unstructured mesh <<%s>>", spaceDim, meshName);
  }
  else{
    Msg::Error("Reading structured MED meshes is not supported");
    return 0;
  }
  med_int vf[3];
  MEDversionLire(fid, &vf[0], &vf[1], &vf[2]);

  // read nodes
#if (MED_MAJOR_NUM == 3)
  med_bool changeOfCoord, geoTransform;
  med_int numNodes = MEDmeshnEntity(fid, meshName, MED_NO_DT, MED_NO_IT, MED_NODE,
                                    MED_NO_GEOTYPE, MED_COORDINATE, MED_NO_CMODE,
                                    &changeOfCoord, &geoTransform);
#else
  med_int numNodes = MEDnEntMaa(fid, meshName, MED_COOR, MED_NOEUD, MED_NONE,
                                MED_NOD);
#endif
  if(numNodes < 0){
    Msg::Error("Could not read number of MED nodes");
    return 0;
  }
  if(numNodes == 0){
    Msg::Error("No nodes in MED mesh");
    return 0;
  }
  std::vector<MVertex*> verts(numNodes);
  std::vector<med_float> coord(spaceDim * numNodes);
#if (MED_MAJOR_NUM == 3)
  if(MEDmeshNodeCoordinateRd(fid, meshName, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE,
                             &coord[0]) < 0){
#else
  std::vector<char> coordName(spaceDim * MED_TAILLE_PNOM + 1);
  std::vector<char> coordUnit(spaceDim * MED_TAILLE_PNOM + 1);
  med_repere rep;
  if(MEDcoordLire(fid, meshName, spaceDim, &coord[0], MED_FULL_INTERLACE,
                  MED_ALL, 0, 0, &rep, &coordName[0], &coordUnit[0]) < 0){
#endif
    Msg::Error("Could not read MED node coordinates");
    return 0;
  }

  std::vector<med_int> nodeTags(numNodes);
#if (MED_MAJOR_NUM == 3)
  if(MEDmeshEntityNumberRd(fid, meshName, MED_NO_DT, MED_NO_IT, MED_NODE,
                           MED_NO_GEOTYPE, &nodeTags[0]) < 0)
#else
  if(MEDnumLire(fid, meshName, &nodeTags[0], numNodes, MED_NOEUD, MED_NONE) < 0)
#endif
    nodeTags.clear();

  for(int i = 0; i < numNodes; i++)
    verts[i] = new MVertex(coord[spaceDim * i],
                           (spaceDim > 1) ? coord[spaceDim * i + 1] : 0.,
                           (spaceDim > 2) ? coord[spaceDim * i + 2] : 0.,
                           0, nodeTags.empty() ? 0 : nodeTags[i]);

  // read elements (loop over all possible MSH element types)
  for(int mshType = 0; mshType < MSH_NUM_TYPE; mshType++){
    med_geometrie_element type = msh2medElementType(mshType);
    if(type == MED_NONE) continue;
#if (MED_MAJOR_NUM == 3)
    med_bool changeOfCoord;
    med_bool geoTransform;
    med_int numEle = MEDmeshnEntity(fid, meshName, MED_NO_DT, MED_NO_IT, MED_CELL,
                                    type, MED_CONNECTIVITY, MED_NODAL, &changeOfCoord,
                                    &geoTransform);
#else
    med_int numEle = MEDnEntMaa(fid, meshName, MED_CONN, MED_MAILLE, type, MED_NOD);
#endif
    if(numEle <= 0) continue;
    int numNodPerEle = type % 100;
    std::vector<med_int> conn(numEle * numNodPerEle);
#if (MED_MAJOR_NUM == 3)
    if(MEDmeshElementConnectivityRd(fid, meshName, MED_NO_DT, MED_NO_IT, MED_CELL,
                                    type, MED_NODAL, MED_FULL_INTERLACE, &conn[0]) < 0){
#else
    if(MEDconnLire(fid, meshName, spaceDim, &conn[0], MED_FULL_INTERLACE, 0, MED_ALL,
                   MED_MAILLE, type, MED_NOD) < 0){
#endif
      Msg::Error("Could not read MED elements");
      return 0;
    }
    std::vector<med_int> fam(numEle, 0);
#if (MED_MAJOR_NUM == 3)
    if(MEDmeshEntityFamilyNumberRd(fid, meshName, MED_NO_DT, MED_NO_IT, MED_CELL,
                                   type, &fam[0]) < 0){
#else
    if(MEDfamLire(fid, meshName, &fam[0], numEle, MED_MAILLE, type) < 0){
#endif
      Msg::Info("No family number for elements: using 0 as default family number");
    }
    std::vector<med_int> eleTags(numEle);
#if (MED_MAJOR_NUM == 3)
    if(MEDmeshEntityNumberRd(fid, meshName, MED_NO_DT, MED_NO_IT, MED_CELL,
                             type, &eleTags[0]) < 0)
#else
    if(MEDnumLire(fid, meshName, &eleTags[0], numEle, MED_MAILLE, type) < 0)
#endif
      eleTags.clear();
    std::map<int, std::vector<MElement*> > elements;
    MElementFactory factory;
    for(int j = 0; j < numEle; j++){
      std::vector<MVertex*> v(numNodPerEle);
      for(int k = 0; k < numNodPerEle; k++)
        v[k] = verts[conn[numNodPerEle * j + med2mshNodeIndex(type, k)] - 1];
      MElement *e = factory.create(mshType, v, eleTags.empty() ? 0 : eleTags[j]);
      if(e) elements[-fam[j]].push_back(e);
    }
    _storeElementsInEntities(elements);
  }
  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(verts);

  // read family info
  med_int numFamilies = MEDnFam(fid, meshName);
  if(numFamilies < 0){
    Msg::Error("Could not read MED families");
    return 0;
  }
  for(int i = 0; i < numFamilies; i++){
#if (MED_MAJOR_NUM == 3)
    med_int numAttrib = (vf[0] == 2) ? MEDnFamily23Attribute(fid, meshName, i + 1) : 0;
    med_int numGroups = MEDnFamilyGroup(fid, meshName, i + 1);
#else
    med_int numAttrib = MEDnAttribut(fid, meshName, i + 1);
    med_int numGroups = MEDnGroupe(fid, meshName, i + 1);
#endif
    if(numAttrib < 0 || numGroups < 0){
      Msg::Error("Could not read MED groups or attributes");
      return 0;
    }
    std::vector<med_int> attribId(numAttrib + 1);
    std::vector<med_int> attribVal(numAttrib + 1);
    std::vector<char> attribDes(MED_TAILLE_DESC * numAttrib + 1);
    std::vector<char> groupNames(MED_TAILLE_LNOM * numGroups + 1);
    char familyName[MED_TAILLE_NOM + 1];
    med_int familyNum;
#if (MED_MAJOR_NUM == 3)
    if(vf[0] == 2){ // MED2 file
      if(MEDfamily23Info(fid, meshName, i + 1, familyName, &attribId[0],
                         &attribVal[0], &attribDes[0], &familyNum,
                         &groupNames[0]) < 0){
        Msg::Error("Could not read info for MED2 family %d", i + 1);
        continue;
      }
    }
    else{
      if(MEDfamilyInfo(fid, meshName, i + 1, familyName, &familyNum,
                       &groupNames[0]) < 0){
        Msg::Error("Could not read info for MED3 family %d", i + 1);
        continue;
      }
    }
#else
    if(MEDfamInfo(fid, meshName, i + 1, familyName, &familyNum, &attribId[0],
                  &attribVal[0], &attribDes[0], &numAttrib, &groupNames[0],
                  &numGroups) < 0){
      Msg::Error("Could not read info for MED family %d", i + 1);
      continue;
    }
#endif
    // family tags are unique (for all dimensions)
    GEntity *ge;
    if((ge = getRegionByTag(-familyNum))){}
    else if((ge = getFaceByTag(-familyNum))){}
    else if((ge = getEdgeByTag(-familyNum))){}
    else ge = getVertexByTag(-familyNum);
    if(ge){
      elementaryNames[std::pair<int, int>(ge->dim(), -familyNum)] = familyName;
      if(numGroups > 0){
        for(int j = 0; j < numGroups; j++){
          char tmp[MED_TAILLE_LNOM + 1];
          strncpy(tmp, &groupNames[j * MED_TAILLE_LNOM], MED_TAILLE_LNOM);
          tmp[MED_TAILLE_LNOM] = '\0';
          // don't use same physical number across dimensions, as e.g. getdp
          // does not support this
          int pnum = setPhysicalName(tmp, ge->dim(), getMaxPhysicalNumber(-1) + 1);
          if(std::find(ge->physicals.begin(), ge->physicals.end(), pnum) ==
             ge->physicals.end())
            ge->physicals.push_back(pnum);
        }
      }
    }
  }

  // check if we need to read some post-processing data later
#if (MED_MAJOR_NUM == 3)
  bool postpro = (MEDnField(fid) > 0) ? true : false;
#else
  bool postpro = (MEDnChamp(fid, 0) > 0) ? true : false;
#endif

  if(MEDfermer(fid) < 0){
    Msg::Error("Unable to close file '%s'", (char*)name.c_str());
    return 0;
  }

  return postpro ? 2 : 1;
}

template<class T>
static void fillElementsMED(med_int family, std::vector<T*> &elements,
                            std::vector<med_int> &conn, std::vector<med_int> &fam,
                            med_geometrie_element &type)
{
  if(elements.empty()) return;
  type = msh2medElementType(elements[0]->getTypeForMSH());
  if(type == MED_NONE){
    Msg::Warning("Unsupported element type in MED format");
    return;
  }
  for(unsigned int i = 0; i < elements.size(); i++){
    elements[i]->setVolumePositive();
    for(int j = 0; j < elements[i]->getNumVertices(); j++)
      conn.push_back(elements[i]->getVertex(med2mshNodeIndex(type, j))->getIndex());
    fam.push_back(family);
  }
}

static void writeElementsMED(med_idt &fid, char *meshName, std::vector<med_int> &conn,
                             std::vector<med_int> &fam, med_geometrie_element type)
{
  if(fam.empty()) return;
#if (MED_MAJOR_NUM == 3)
  if(MEDmeshElementWr(fid, meshName, MED_NO_DT, MED_NO_IT, 0., MED_CELL, type,
                      MED_NODAL, MED_FULL_INTERLACE, (med_int)fam.size(),
                      &conn[0], MED_FALSE, 0, MED_FALSE, 0, MED_TRUE, &fam[0]) < 0)
#else
  if(MEDelementsEcr(fid, meshName, (med_int)3, &conn[0], MED_FULL_INTERLACE,
                    0, MED_FAUX, 0, MED_FAUX, &fam[0], (med_int)fam.size(),
                    MED_MAILLE, type, MED_NOD) < 0)
#endif
    Msg::Error("Could not write MED elements");
}

int GModel::writeMED(const std::string &name, bool saveAll, double scalingFactor)
{
  med_idt fid = MEDouvrir((char*)name.c_str(), MED_CREATION);
  if(fid < 0){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  // write header
  if(MEDfichDesEcr(fid, (char*)"MED file generated by Gmsh") < 0){
    Msg::Error("Unable to write MED descriptor");
    return 0;
  }

  char *meshName = (char*)getName().c_str();

  // Gmsh always writes 3D unstructured meshes
#if (MED_MAJOR_NUM == 3)
  char dtUnit[MED_SNAME_SIZE + 1] = "";
  char axisName[3 * MED_SNAME_SIZE + 1] = "";
  char axisUnit[3 * MED_SNAME_SIZE + 1] = "";
  if(MEDmeshCr(fid, meshName, 3, 3, MED_UNSTRUCTURED_MESH, "Mesh created with Gmsh",
               dtUnit, MED_SORT_DTIT, MED_CARTESIAN, axisName, axisUnit) < 0){
#else
  if(MEDmaaCr(fid, meshName, 3, MED_NON_STRUCTURE,
              (char*)"Mesh created with Gmsh") < 0){
#endif
    Msg::Error("Could not create MED mesh");
    return 0;
  }

  // if there are no physicals we save all the elements
  if(noPhysicalGroups()) saveAll = true;

  // index the vertices we save in a continuous sequence (MED
  // connectivity is given in terms of vertex indices)
  indexMeshVertices(saveAll);

  // get a vector containing all the geometrical entities in the
  // model (the ordering of the entities must be the same as the one
  // used during the indexing of the vertices)
  std::vector<GEntity*> entities;
  getEntities(entities);

  std::map<GEntity*, int> families;
  // write the families
  {
    // always create a "0" family, with no groups or attributes
#if (MED_MAJOR_NUM == 3)
    if(MEDfamilyCr(fid, meshName, "F_0", 0, 0, "") < 0)
#else
    if(MEDfamCr(fid, meshName, (char*)"F_0", 0, 0, 0, 0, 0, 0, 0) < 0)
#endif
      Msg::Error("Could not create MED family 0");

    // create one family per elementary entity, with one group per
    // physical entity and no attributes
    for(unsigned int i = 0; i < entities.size(); i++){
      if(saveAll || entities[i]->physicals.size()){
        int num = - ((int)families.size() + 1);
        families[entities[i]] = num;
        std::ostringstream fs;
        fs << entities[i]->dim() << "D_" << entities[i]->tag();
        std::string familyName = "F_" + fs.str();
        std::string groupName;
        for(unsigned j = 0; j < entities[i]->physicals.size(); j++){
          std::string tmp = getPhysicalName
            (entities[i]->dim(), entities[i]->physicals[j]);
          if(tmp.empty()){ // create unique name
            std::ostringstream gs;
            gs << entities[i]->dim() << "D_" << entities[i]->physicals[j];
            groupName += "G_" + gs.str();
          }
          else
            groupName += tmp;
          groupName.resize((j + 1) * MED_TAILLE_LNOM, ' ');
        }
#if (MED_MAJOR_NUM == 3)
        if(MEDfamilyCr(fid, meshName, familyName.c_str(),
                       (med_int)num, (med_int)entities[i]->physicals.size(),
                       groupName.c_str()) < 0)
#else
        if(MEDfamCr(fid, meshName, (char*)familyName.c_str(),
                    (med_int)num, 0, 0, 0, 0, (char*)groupName.c_str(),
                    (med_int)entities[i]->physicals.size()) < 0)
#endif
          Msg::Error("Could not create MED family %d", num);
      }
    }
  }

  // write the nodes
  {
    std::vector<med_float> coord;
    std::vector<med_int> fam;
    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){
          coord.push_back(v->x() * scalingFactor);
          coord.push_back(v->y() * scalingFactor);
          coord.push_back(v->z() * scalingFactor);
          fam.push_back(0); // we never create node families
        }
      }
    }
    if(fam.empty()){
      Msg::Error("No nodes to write in MED mesh");
      return 0;
    }
#if (MED_MAJOR_NUM == 3)
    if(MEDmeshNodeWr(fid, meshName, MED_NO_DT, MED_NO_IT, 0., MED_FULL_INTERLACE,
                     (med_int)fam.size(), &coord[0], MED_FALSE, "", MED_FALSE, 0,
                     MED_TRUE, &fam[0]) < 0)
#else
    char coordName[3 * MED_TAILLE_PNOM + 1] =
      "x               y               z               ";
    char coordUnit[3 * MED_TAILLE_PNOM + 1] =
      "unknown         unknown         unknown         ";
    if(MEDnoeudsEcr(fid, meshName, (med_int)3, &coord[0], MED_FULL_INTERLACE,
                    MED_CART, coordName, coordUnit, 0, MED_FAUX, 0, MED_FAUX,
                    &fam[0], (med_int)fam.size()) < 0)
#endif
      Msg::Error("Could not write nodes");
  }

  // write the elements
  {
    { // points
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(viter it = firstVertex(); it != lastVertex(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->points, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // lines
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(eiter it = firstEdge(); it != lastEdge(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->lines, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // triangles
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(fiter it = firstFace(); it != lastFace(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->triangles, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // quads
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(fiter it = firstFace(); it != lastFace(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->quadrangles, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // tets
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(riter it = firstRegion(); it != lastRegion(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->tetrahedra, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // hexas
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(riter it = firstRegion(); it != lastRegion(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->hexahedra, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // prisms
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(riter it = firstRegion(); it != lastRegion(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->prisms, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // pyramids
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(riter it = firstRegion(); it != lastRegion(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->pyramids, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
  }

  if(MEDfermer(fid) < 0){
    Msg::Error("Unable to close file '%s'", (char*)name.c_str());
    return 0;
  }

  return 1;
}

#else

int GModel::readMED(const std::string &name)
{
  Msg::Error("Gmsh must be compiled with MED support to read '%s'",
             name.c_str());
  return 0;
}
Пример #9
0
int GModel::writeINP(const std::string &name, bool saveAll, bool saveGroupsOfNodes,
                     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;

  indexMeshVertices(saveAll);
  std::vector<GEntity*> entities;
  getEntities(entities);

  fprintf(fp, "*Heading\n");
  fprintf(fp, " %s\n", name.c_str());

  fprintf(fp, "*Node\n");
  for(unsigned int i = 0; i < entities.size(); i++)
    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++)
      entities[i]->mesh_vertices[j]->writeINP(fp, scalingFactor);

  for(viter it = firstVertex(); it != lastVertex(); ++it){
    writeElementsINP(fp, *it, (*it)->points, saveAll);
  }
  for(eiter it = firstEdge(); it != lastEdge(); ++it){
    writeElementsINP(fp, *it, (*it)->lines, saveAll);
  }
  for(fiter it = firstFace(); it != lastFace(); ++it){
    writeElementsINP(fp, *it, (*it)->triangles, saveAll);
    writeElementsINP(fp, *it, (*it)->quadrangles, saveAll);
  }
  for(riter it = firstRegion(); it != lastRegion(); ++it){
    writeElementsINP(fp, *it, (*it)->tetrahedra, saveAll);
    writeElementsINP(fp, *it, (*it)->hexahedra, saveAll);
    writeElementsINP(fp, *it, (*it)->prisms, saveAll);
    writeElementsINP(fp, *it, (*it)->pyramids, saveAll);
  }

  std::map<int, std::vector<GEntity*> > groups[4];
  getPhysicalGroups(groups);

  // save elements sets for each physical group
  for(int dim = 0; dim <= 3; dim++){
    for(std::map<int, std::vector<GEntity*> >::iterator it = groups[dim].begin();
        it != groups[dim].end(); it++){
      std::vector<GEntity *> &entities = it->second;
      fprintf(fp, "*ELSET,ELSET=%s\n", physicalName(this, dim, it->first).c_str());
      int n = 0;
      for(unsigned int i = 0; i < entities.size(); i++){
        for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
          MElement *e = entities[i]->getMeshElement(j);
          if(n && !(n % 10)) fprintf(fp, "\n");
          fprintf(fp, "%d, ", e->getNum());
          n++;
        }
      }
      fprintf(fp, "\n");
    }
  }

  // save node sets for each physical group
  if(saveGroupsOfNodes){
    for(int dim = 1; dim <= 3; dim++){
      for(std::map<int, std::vector<GEntity*> >::iterator it = groups[dim].begin();
          it != groups[dim].end(); it++){
        std::set<MVertex*> nodes;
        std::vector<GEntity *> &entities = it->second;
        for(unsigned int i = 0; i < entities.size(); i++){
          for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
            MElement *e = entities[i]->getMeshElement(j);
            for (int k = 0; k < e->getNumVertices(); k++)
              nodes.insert(e->getVertex(k));
          }
        }
        fprintf(fp, "*NSET,NSET=%s\n", physicalName(this, dim, it->first).c_str());
        int n = 0;
        for(std::set<MVertex*>::iterator it2 = nodes.begin(); it2 != nodes.end(); it2++){
          if(n && !(n % 10)) fprintf(fp, "\n");
          fprintf(fp, "%d, ", (*it2)->getIndex());
          n++;
        }
        fprintf(fp, "\n");
      }
    }
  }

  fclose(fp);
  return 1;
}
Пример #10
0
int GModel::writeSU2(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;
  }

  int ndime = getDim();
  if(ndime != 2 && ndime != 3){
    Msg::Error("SU2 mesh output valid only for 2D or 3D models (not %dD)", ndime);
    fclose(fp);
    return 0;
  }

  if(noPhysicalGroups()) saveAll = true;

  fprintf(fp, "NDIME= %d\n", ndime);

  // all interior elements are printed in a single section; indices start at 0;
  // node ordering is the same as VTK
  int nelem = 0;
  if(ndime == 2){
    for(fiter it = firstFace(); it != lastFace(); it++)
      if(saveAll || (*it)->physicals.size()) nelem += (*it)->getNumMeshElements();
  }
  else{
    for(riter it = firstRegion(); it != lastRegion(); it++)
      if(saveAll || (*it)->physicals.size()) nelem += (*it)->getNumMeshElements();
  }
  int npoin = indexMeshVertices(saveAll);

  Msg::Info("Writing %d elements and %d vertices", nelem, npoin);

  // elements
  fprintf(fp, "NELEM= %d\n", nelem);
  int num = 0;
  if(ndime == 2){
    for(fiter it = firstFace(); it != lastFace(); it++)
      if(saveAll || (*it)->physicals.size())
        for(unsigned int i = 0; i < (*it)->getNumMeshElements(); i++)
          (*it)->getMeshElement(i)->writeSU2(fp, num++);
  }
  else{
    for(riter it = firstRegion(); it != lastRegion(); it++)
      if(saveAll || (*it)->physicals.size())
        for(unsigned int i = 0; i < (*it)->getNumMeshElements(); i++)
          (*it)->getMeshElement(i)->writeSU2(fp, num++);
  }

  // vertices
  fprintf(fp, "NPOIN= %d\n", npoin);
  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++)
      entities[i]->mesh_vertices[j]->writeSU2(fp, ndime, scalingFactor);

  // markers for physical groups of dimension (ndime - 1)
  std::map<int, std::vector<GEntity*> > groups[4];
  getPhysicalGroups(groups);
  int nmark = groups[ndime - 1].size();
  if(nmark){
    fprintf(fp, "NMARK= %d\n", nmark);
    for(std::map<int, std::vector<GEntity*> >::iterator it = groups[ndime - 1].begin();
        it != groups[ndime - 1].end(); it++){
      std::vector<GEntity *> &entities = it->second;
      int n = 0;
      for(unsigned int i = 0; i < entities.size(); i++)
        n += entities[i]->getNumMeshElements();
      if(n){
        fprintf(fp, "MARKER_TAG= %s\n", physicalName(this, ndime - 1, it->first).c_str());
        fprintf(fp, "MARKER_ELEMS= %d\n", n);
        for(unsigned int i = 0; i < entities.size(); i++)
          for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++)
            entities[i]->getMeshElement(j)->writeSU2(fp, -1);
      }
    }
  }

  fclose(fp);
  return 1;
}