Example #1
0
void build_local_element_map(RegionVector &part_mesh,
			     std::vector<INT> &local_element_map)
{
  size_t global = 0;
  size_t offset = 0;
  for (size_t p = 0; p < part_mesh.size(); p++) {

    Ioss::ElementBlockContainer ebs = part_mesh[p]->get_element_blocks();
    Ioss::ElementBlockContainer::const_iterator i = ebs.begin();

    while (i != ebs.end()) {
      Ioss::ElementBlock *eb = *i++; 
      size_t num_elem  = eb->get_property("entity_count").get_int();
      if (entity_is_omitted(eb)) {
	// Fill local_element_map with -1 for the omitted elements.
	for (size_t j = 0; j < num_elem; j++) {
	  local_element_map[offset+j] = -1;
	}
      } else {
	for (size_t j = 0; j < num_elem; j++) {
	  local_element_map[offset+j] = global++;
	}
      }
      offset += num_elem;
    }
  }
}
Example #2
0
// records regions of contiguous identity in the alignment
void CColorspaceUtilities::FindIndenticalRegions(char* pReference, char* pQuery, const unsigned short pairwiseLen, RegionVector& rv) {

    for(unsigned short i = 0; i < pairwiseLen; i++) {
        if(pReference[i] == pQuery[i]) {
            RegionT r(i);
            unsigned short end = i;
            while((end < pairwiseLen) && (pReference[end] == pQuery[end])) {
                ++r.Length;
                ++end;
            }
            rv.push_back(r);
            i = end;
        }
    }
}
Example #3
0
void eliminate_omitted_nodes(RegionVector &part_mesh,
			     std::vector<INT> &global_node_map,
			     std::vector<INT> &local_node_map)
{
  size_t offset = 0;
  size_t j = 0;
  size_t part_count = part_mesh.size();
  for (size_t p = 0; p < part_count; p++) {
    bool has_omissions = part_mesh[p]->get_property("block_omission_count").get_int() > 0;
    Ioss::NodeBlock *nb = part_mesh[p]->get_node_blocks()[0];
    size_t loc_size = nb->get_property("entity_count").get_int();
    if (has_omissions) {
      // If there are any omitted element blocks for this part, don't
      // map the nodes that are only connected to omitted element
      // blocks.
      std::vector<char> node_status;
      nb->get_field_data("node_connectivity_status", node_status);
      for (size_t i=0; i < node_status.size(); i++) {
	if (node_status[i] != 1) {
	  local_node_map[offset+i] = j;
	  global_node_map.push_back(j+1);
	  j++;
	} else {
	  local_node_map[offset+i] = -1;
	}
      }
    } else {
      for (size_t i=0; i < loc_size; i++) {
	local_node_map[offset+i] = j;
	global_node_map.push_back(j+1);
	j++;
      }
    }
    offset += loc_size;
  }
}
Example #4
0
bool
Probes::JITWatcher::CollectNativeRegions(RegionVector &regions,
                                         JSRuntime *rt,
                                         mjit::JITChunk *jit,
                                         mjit::JSActiveFrame *outerFrame,
                                         mjit::JSActiveFrame **inlineFrames)
{
    regions.resize(jit->nInlineFrames * 2 + 2);

    mjit::JSActiveFrame **stack =
        rt->array_new<mjit::JSActiveFrame*>(jit->nInlineFrames+2);
    if (!stack)
        return false;
    uint32_t depth = 0;
    uint32_t ip = 0;

    stack[depth++] = NULL;
    stack[depth++] = outerFrame;
    regions[0].frame = outerFrame;
    regions[0].script = outerFrame->script;
    regions[0].pc = outerFrame->script->code;
    regions[0].enter = true;
    ip++;

    for (uint32_t i = 0; i <= jit->nInlineFrames; i++) {
        mjit::JSActiveFrame *frame = (i < jit->nInlineFrames) ? inlineFrames[i] : outerFrame;

        // Not a down frame; pop the current frame, then pop until we reach
        // this frame's parent, recording subframe ends as we go
        while (stack[depth-1] != frame->parent) {
            depth--;
            JS_ASSERT(depth > 0);
            // Pop up from regions[ip-1].frame to top of the stack: start a
            // region in the destination frame and close off the source
            // (origin) frame at the end of its script
            mjit::JSActiveFrame *src = regions[ip-1].frame;
            mjit::JSActiveFrame *dst = stack[depth-1];
            JS_ASSERT_IF(!dst, i == jit->nInlineFrames);
            regions[ip].frame = dst;
            regions[ip].script = dst ? dst->script : NULL;
            regions[ip].pc = src->parentPC + 1;
            regions[ip-1].endpc = src->script->code + src->script->length;
            regions[ip].enter = false;
            ip++;
        }

        if (i < jit->nInlineFrames) {
            // Push a frame (enter an inlined function). Start a region at the
            // beginning of the new frame's script, and end the previous region
            // at parentPC.
            stack[depth++] = frame;

            regions[ip].frame = frame;
            regions[ip].script = frame->script;
            regions[ip].pc = frame->script->code;
            regions[ip-1].endpc = frame->parentPC;
            regions[ip].enter = true;
            ip++;
        }
    }

    // Final region is always zero-length and not particularly useful
    ip--;
    regions.popBack();

    mjit::JSActiveFrame *prev = NULL;
    for (NativeRegion *iter = regions.begin(); iter != regions.end(); ++iter) {
        mjit::JSActiveFrame *frame = iter->frame;
        if (iter->enter) {
            // Pushing down a frame, so region starts at the beginning of the
            // (destination) frame
            iter->mainOffset = frame->mainCodeStart;
            iter->stubOffset = frame->stubCodeStart;
        } else {
            // Popping up a level, so region starts at the end of the (source) frame
            iter->mainOffset = prev->mainCodeEnd;
            iter->stubOffset = prev->stubCodeEnd;
        }
        prev = frame;
    }

    JS_ASSERT(ip == 2 * jit->nInlineFrames + 1);
    rt->array_delete(stack);

    // All of the stub code comes immediately after the main code
    for (NativeRegion *iter = regions.begin(); iter != regions.end(); ++iter)
        iter->stubOffset += outerFrame->mainCodeEnd;

    return true;
}
Example #5
0
void generate_element_ids(RegionVector &part_mesh,
			  const std::vector<INT> &local_element_map,
			  std::vector<INT> &global_element_map)
{
  // Follow same logic as 'build_local_element_map' to ensure elements
  // are processed in same order.

  // Many models do not use the element number map at all, so they
  // will have a 1..numel map.  If all parts have that, then we don't
  // want to do any fancy duplicate removal and other processing, just
  // output a 1..numel map for the output mesh...  We still generate
  // the global_element_map, but check whether any of the part blocks
  // have a non-1..numel map...
  bool has_map = false;
  size_t offset = 0;
  for (size_t p = 0; p < part_mesh.size(); p++) {
    Ioss::ElementBlockContainer ebs = part_mesh[p]->get_element_blocks();
    Ioss::ElementBlockContainer::const_iterator i = ebs.begin();

    while (i != ebs.end()) {
      Ioss::ElementBlock *eb = *i++; 
      INT num_elem  = eb->get_property("entity_count").get_int();
      if (!entity_is_omitted(eb)) {
	std::vector<INT> part_ids;
	eb->get_field_data("ids", part_ids);

	if (!has_map) { 
	  INT eb_offset = eb->get_offset();
	  for (INT j = 0; j < num_elem; j++) {
	    if (part_ids[j] != eb_offset+j+1) {
	      has_map = true;
	      break;
	    }
	  }
	}

	for (INT j = 0; j < num_elem; j++) {
	  INT gpos = local_element_map[offset+j];
	  if (gpos >= 0)
	    global_element_map[gpos] = part_ids[j];
	}
      }
      offset += num_elem;
    }
  }
  // Check for duplicates...
  // NOTE: Used to use an indexed sort here, but if there was a
  // duplicate id, it didnt really care whether part 1 or part N's
  // index came first which causes really screwy element maps.
  // Instead, lets sort a vector containing pairs of <id, index> where
  // the index will always? increase for increasing part numbers...
  std::vector<std::pair<INT,INT> > index(global_element_map.size());
  for (size_t i=0; i < index.size(); i++) {
    index[i] = std::make_pair(global_element_map[i],(INT)i);
  }

  std::sort(index.begin(), index.end());

  INT max_id = index[index.size()-1].first + 1;
  
  size_t beg = 0;
  for (size_t i=1; i < index.size(); i++) {
    if (index[beg].first == index[i].first) {
      // Duplicate found... Assign it a new id greater than any
      // existing id...  (What happens if we exceed INT_MAX?)
      global_element_map[index[i].second] = max_id++;
      // Keep 'beg' the same in case multiple duplicate of this value.
    } else {
      beg = i;
    }
  }
}
Example #6
0
  void build_reverse_node_map(Ioss::Region &global,
			      RegionVector &part_mesh,
			      std::vector<INT> &global_node_map,
			      std::vector<INT> &local_node_map)
  {
    // Instead of using <set> and <map>, consider using a sorted vector...
    // Append all local node maps to the global node map.
    // Sort the global node map
    // Remove duplicates.
    // Position within map is now the map...
    // When building the local-part node to global id, use binary_search...

    size_t part_count = part_mesh.size();

    // Global node map and count.
    std::vector<std::vector<int> > global_nodes(part_count);

    size_t tot_size = 0;
    for (size_t p = 0; p < part_count; p++) {
      Ioss::NodeBlock *nb = part_mesh[p]->get_node_blocks()[0];
      size_t loc_size = nb->get_property("entity_count").get_int();
      tot_size += loc_size;
      global_nodes[p].resize(loc_size);
    }
    global_node_map.resize(tot_size);

    size_t offset = 0;
    bool any_omitted_nodes = false;
    for (size_t p = 0; p < part_count; p++) {
      Ioss::NodeBlock *nb = part_mesh[p]->get_node_blocks()[0];
      nb->get_field_data("ids", global_nodes[p]);

      // If there are any omitted element blocks for this part, set
      // the global id of any nodes that are only connected to omitted
      // element blocks to 0.
      bool has_omissions = part_mesh[p]->get_property("block_omission_count").get_int() > 0;
      if (has_omissions) {
	std::vector<char> node_status;
	nb->get_field_data("node_connectivity_status", node_status);
	for (size_t i=0; i < node_status.size(); i++) {
	  if (node_status[i] == 1) {
	    any_omitted_nodes = true;
	    global_nodes[p][i] = 0;
	  }
	}
      }

      std::copy(global_nodes[p].begin(), global_nodes[p].end(), &global_node_map[offset]);
      offset += global_nodes[p].size();
    }

    // Now, sort the global_node_map array and remove duplicates...
    uniqify(global_node_map);

    // If any omitted nodes, remove them from the global_node_map.
    // The id will be 0
    if (any_omitted_nodes) {
      typename std::vector<INT>::iterator pos = std::remove(global_node_map.begin(),
						   global_node_map.end(), 0);
      global_node_map.erase(pos, global_node_map.end());
    }

    size_t output_node_count = global_node_map.size();

    // See whether the node numbers are contiguous.  If so, we can map
    // the nodes back to their original location. Since the nodes are
    // sorted and there are no duplicates, we just need to see if the id
    // at global_node_map.size() == global_node_map.size();
    size_t max_id = global_node_map[output_node_count-1];

    bool is_contiguous = max_id == output_node_count;
    std::cerr  << "Node map " << (is_contiguous ? "is" : "is not") << " contiguous.\n";

    // Create the map that maps from a local part node to the
    // global map. This combines the mapping local part node to
    // 'global id' and then 'global id' to global position. The
    // mapping is now a direct lookup instead of a lookup followed by
    // a reverse map.
    typedef typename std::vector<INT>::iterator V_INT_iterator;
    V_INT_iterator cur_pos = global_node_map.begin();
    for (size_t p = 0; p < part_count; p++) {
      size_t noffset = part_mesh[p]->get_property("node_offset").get_int();
      size_t node_count = global_nodes[p].size();
      for (size_t i = 0; i < node_count; i++) {
	INT global_node = global_nodes[p][i];

	if (global_node > 0) {
	if (cur_pos == global_node_map.end() || *cur_pos != global_node) {
	  std::pair<V_INT_iterator, V_INT_iterator> iter = std::equal_range(global_node_map.begin(),
									    global_node_map.end(),
									    global_node);
	  if (iter.first == iter.second) {
	    INT n = global_node;
	    std::cerr << n << "\n";
	    SMART_ASSERT(iter.first != iter.second);
	  }
	  cur_pos = iter.first;
	}
	size_t nodal_value = cur_pos - global_node_map.begin();
	local_node_map[noffset+i] = nodal_value;
	++cur_pos;
	} else {
	  local_node_map[noffset+i] = -1;
	}
      }				
    }
    
    // Update the nodal ids to give a unique, non-repeating set.  If contiguous, then
    // there is nothing to do.  If not contiguous, then need to determine if there are any
    // repeats (id reuse) and if so, generate a new id for the repeated uses.
    if (!is_contiguous) {
      bool repeat_found = false;
      INT id_last = global_node_map[0];
      for (size_t i=1; i < output_node_count; i++) {
	if (global_node_map[i] == id_last) {
	  global_node_map[i] = ++max_id;
	  repeat_found = true;
	} else {
	  id_last = global_node_map[i];
	}
      }
      if (repeat_found) {
	std::cerr  << "Duplicate node ids were found. Their ids have been renumbered to remove duplicates.\n";
      }
    }
  }
void match_node_xyz(RegionVector &part_mesh,
		    double tolerance,
		    std::vector<INT> &global_node_map, std::vector<INT> &local_node_map)
{
  // See if any omitted element blocks...
  bool has_omissions = false;
  for (auto & elem : part_mesh) {
    if (elem->get_property("block_omission_count").get_int() > 0) {
      has_omissions = true;
      break;
    }
  }

  if (!has_omissions) {
    for (size_t i=0; i < local_node_map.size(); i++) {
      local_node_map[i] = i;
    }
  } else {
    std::vector<INT> dummy;
    eliminate_omitted_nodes(part_mesh, dummy, local_node_map);

    // The local_node_map is not quite in the correct format after the
    // call to 'eliminate_omitted_nodes'.  We need all non-omitted
    // nodes to have local_node_map[i] == i.
    for (size_t i=0; i < local_node_map.size(); i++) {
      if (local_node_map[i] >= 0) local_node_map[i] = i;
    }
  }
  
  size_t part_count = part_mesh.size();
  enum {X=0, Y=1, Z=2};

  for (size_t ip=0; ip < part_count; ip++) {
    vector3d i_max;
    vector3d i_min;
    std::vector<double> i_coord;
    Ioss::NodeBlock *inb = part_mesh[ip]->get_node_blocks()[0];
    inb->get_field_data("mesh_model_coordinates", i_coord);
    find_range(i_coord, i_min, i_max);
    
    size_t i_offset = part_mesh[ip]->get_property("node_offset").get_int();

    for (size_t jp=ip+1; jp < part_count; jp++) {
      vector3d j_max;
      vector3d j_min;
      std::vector<double> j_coord;
      Ioss::NodeBlock *jnb = part_mesh[jp]->get_node_blocks()[0];
      jnb->get_field_data("mesh_model_coordinates", j_coord);
      find_range(j_coord, j_min, j_max);

      size_t j_offset = part_mesh[jp]->get_property("node_offset").get_int();

      // See if the ranges overlap...
      vector3d max;
      vector3d min;
      max.x = std::min(i_max.x, j_max.x);
      max.y = std::min(i_max.y, j_max.y);
      max.z = std::min(i_max.z, j_max.z);

      min.x = std::max(i_min.x, j_min.x);
      min.y = std::max(i_min.y, j_min.y);
      min.z = std::max(i_min.z, j_min.z);

      double delta[3];
      int XYZ = X;
      delta[XYZ] = max.x - min.x;
      delta[Y] = max.y - min.y;
      if (delta[Y] > delta[XYZ])
	XYZ = Y;
      delta[Z] = max.z - min.z;
      if (delta[Z] > delta[XYZ])
	XYZ = Z;

      double epsilon = (delta[X] + delta[Y] + delta[Z]) / 1.0e3;
      if (epsilon < 0.0) {
	std::cout << "Parts " << ip << " and " << jp << " do not overlap.\n";
	continue;
      }

      min -= epsilon;
      max += epsilon;

      if (tolerance >= 0.0) epsilon = tolerance;

      std::vector<INT> j_inrange;
      std::vector<INT> i_inrange;

      find_in_range(j_coord, min, max, j_inrange);
      find_in_range(i_coord, min, max, i_inrange);

      // Index sort all nodes on the coordinate range with the maximum delta.
      index_coord_sort(i_coord, i_inrange, XYZ);
      index_coord_sort(j_coord, j_inrange, XYZ);

      if (i_inrange.size() < j_inrange.size()) {
	do_matching(i_inrange, i_coord, i_offset,
		    j_inrange, j_coord, j_offset,
		    epsilon, XYZ, local_node_map);
      } else {
	do_matching(j_inrange, j_coord, j_offset,
		    i_inrange, i_coord, i_offset,
		    epsilon, XYZ, local_node_map);
      }
    }
  }

  // Build the global and local maps...
  size_t j = 1;
  for (size_t i=0; i < local_node_map.size(); i++) {
    if (local_node_map[i] == (INT)i) {
      global_node_map.push_back(j);
      local_node_map[i] = j-1;
      j++;
    } else if (local_node_map[i] >= 0) {
      local_node_map[i] = local_node_map[local_node_map[i]];
    }
  }
}
Example #8
0
bool ScanMatcher::scanMatchingLChierarchical(OptimizableGraph::VertexSet& referenceVset,  OptimizableGraph::Vertex* _referenceVertex, OptimizableGraph::VertexSet& currvset, OptimizableGraph::Vertex* _currentVertex,  std::vector<SE2>& trel, double maxScore){ 
  //cerr << "Loop Closing Scan Matching" << endl;
  //cerr << "Size of Vset " << referenceVset.size() << endl;
  VertexSE2* currentVertex=dynamic_cast<VertexSE2*>(_currentVertex);
  VertexSE2* referenceVertex =dynamic_cast<VertexSE2*>(_referenceVertex);

  resetGrid();
  trel.clear();

  RawLaser::Point2DVector scansInRefVertex;
  transformPointsFromVSet(referenceVset, _referenceVertex, scansInRefVertex);
  _grid.addAndConvolvePoints<RawLaser::Point2DVector>(scansInRefVertex.begin(), scansInRefVertex.end(), _kernel);
  
  RawLaser::Point2DVector scansInCurVertex;
  transformPointsFromVSet(currvset, _currentVertex, scansInCurVertex);

  Vector2dVector reducedScans;
  CharGrid::subsample(reducedScans, scansInCurVertex, 0.1);
  //cerr << "subsampling: " << scansInCurVertex.size() << " -> " << reducedScans.size() << endl;

  SE2 delta = referenceVertex->estimate().inverse() * currentVertex->estimate();

  Vector3d initGuess(delta.translation().x(), delta.translation().y(), delta.rotation().angle());

  Vector3f lower(-2.+initGuess.x(), -2.+initGuess.y(), -1.+initGuess.z());
  Vector3f upper(+2.+initGuess.x(),  2.+initGuess.y(),  1.+initGuess.z()); 

  RegionVector regions;
  Region reg;
  reg.lowerLeft  = lower;
  reg.upperRight = upper;
  regions.push_back(reg);

  std::vector<MatcherResult> mresvec;
  double thetaRes = 0.025; // was 0.0125*.5
 
  // clock_t t_ini, t_fin;
  // double secs;
  
  // t_ini = clock();
  _grid.hierarchicalSearch(mresvec, reducedScans, regions, thetaRes, maxScore, 0.5, 0.5, 0.2, 3);
  // t_fin = clock();
  // secs = (double)(t_fin - t_ini) / CLOCKS_PER_SEC;
  // printf("%.16g ms. Matcher results: %i\n", secs * 1000.0, (int) mresvec.size());

  if (mresvec.size()){
    Vector3d adj=mresvec[0].transformation;
    SE2 transf;
    transf.setTranslation(Vector2d(adj.x(), adj.y()));
    transf.setRotation(adj.z());
    //    cerr <<  " bestScore = " << mresvec[0].score << endl; 
    //cerr << "Found Loop Closure Edge. Transf: " << adj.x() << " " << adj.y() << " " << adj.z() << endl << endl;

    trel.push_back(transf);
  }

  if (trel.size())
    return true;

  return false;
}
Example #9
0
bool ScanMatcher::scanMatchingLC(OptimizableGraph::VertexSet& referenceVset,  OptimizableGraph::Vertex* _referenceVertex, OptimizableGraph::VertexSet& currvset, OptimizableGraph::Vertex* _currentVertex,  std::vector<SE2>& trel, double maxScore){ 
  cerr << "Loop Closing Scan Matching" << endl;
  //cerr << "Size of Vset " << referenceVset.size() << endl;
  VertexSE2* referenceVertex =dynamic_cast<VertexSE2*>(_referenceVertex);

  resetGrid();
  trel.clear();
  
  RawLaser::Point2DVector scansInRefVertex;
  transformPointsFromVSet(referenceVset, _referenceVertex, scansInRefVertex);
  _grid.addAndConvolvePoints<RawLaser::Point2DVector>(scansInRefVertex.begin(), scansInRefVertex.end(), _kernel);

  RawLaser::Point2DVector scansInCurVertex;
  transformPointsFromVSet(currvset, _currentVertex, scansInCurVertex);

  Vector2dVector reducedScans;
  CharGrid::subsample(reducedScans, scansInCurVertex, 0.1);

  RegionVector regions;
  RegionVector regionspi;
  for (OptimizableGraph::VertexSet::iterator it = referenceVset.begin(); it != referenceVset.end(); it++){
    VertexSE2 *vertex = (VertexSE2*) *it;

    Region reg;
    SE2 relposv(.0, .0, .0);
    if (vertex->id() != referenceVertex->id())
      relposv = referenceVertex->estimate().inverse() * vertex->estimate();
    
    Vector3f lower(-.5+relposv.translation().x(), -2.+relposv.translation().y(), -1.+relposv.rotation().angle());
    Vector3f upper( .5+relposv.translation().x(),  2.+relposv.translation().y(),  1.+relposv.rotation().angle());
    reg.lowerLeft  = lower;
    reg.upperRight = upper;
    regions.push_back(reg);
  
    lower[2] += M_PI;
    upper[2] += M_PI; 
    reg.lowerLeft  = lower;
    reg.upperRight = upper;
    regionspi.push_back(reg);
  }

  std::vector<MatcherResult> mresvec;
  double thetaRes = 0.025; // was 0.0125*.5
  //Results discretization
  double dx = 0.5, dy = 0.5, dth = 0.2;
  
  std::map<DiscreteTriplet, MatcherResult> resultsMap;
  
  clock_t t_ini, t_fin;
  double secs;
  
  t_ini = clock();
  _grid.greedySearch(mresvec, reducedScans, regions, thetaRes, maxScore, dx, dy, dth);
  t_fin = clock();
  secs = (double)(t_fin - t_ini) / CLOCKS_PER_SEC;
  printf("%.16g ms. Matcher results: %i\n", secs * 1000.0, (int) mresvec.size());
  
  if (mresvec.size()){
    mresvec[0].transformation[2] = normalize_theta(mresvec[0].transformation[2]);
    cerr << "Found Loop Closure Edge. Transf: " << mresvec[0].transformation.x() << " " << mresvec[0].transformation.y() << " " << mresvec[0].transformation.z() << endl;

    CharGrid::addToPrunedMap(resultsMap, mresvec[0], dx, dy, dth);
  }

  t_ini = clock();
  _grid.greedySearch(mresvec, reducedScans, regionspi, thetaRes, maxScore, dx, dy, dth);
  t_fin = clock();
  secs = (double)(t_fin - t_ini) / CLOCKS_PER_SEC;
  printf("%.16g ms. Matcher results: %i\n", secs * 1000.0, (int) mresvec.size());

  if (mresvec.size()){
    mresvec[0].transformation[2] = normalize_theta(mresvec[0].transformation[2]);
    cerr << "Found Loop Closure Edge PI. Transf: " << mresvec[0].transformation.x() << " " << mresvec[0].transformation.y() << " " << mresvec[0].transformation.z() << endl;

    CharGrid::addToPrunedMap(resultsMap, mresvec[0], dx, dy, dth);
  }

  for (std::map<DiscreteTriplet, MatcherResult>::iterator it = resultsMap.begin(); it!= resultsMap.end(); it++){
    MatcherResult res = it->second;
    Vector3d adj=res.transformation;
    SE2 transf;
    transf.setTranslation(Vector2d(adj.x(), adj.y()));
    transf.setRotation(normalize_theta(adj.z()));
    trel.push_back(transf);
    
    std::cerr << "Final result: " << transf.translation().x() << " " << transf.translation().y() << " " << transf.rotation().angle() << std::endl;
  }

  if (trel.size())
    return true;

  return false;
}
Example #10
0
void AlignmentView::paintEvent(QPaintEvent * event)
{
	DrawingArea::paintEvent(event);
	
	if ( alignment == 0 )
	{
		return;
	}
	
	if ( width() <= frameWidth() * 2 )
	{
		return;
	}
	
	QPainter painter(this);
//	painter.setRenderHints(0);
	
	QImage image(width() - frameWidth() * 2, height() - frameWidth() * 2, QImage::Format_RGB32);
	
//	setColors();
	
	image.setColorCount(62);
	image.setColorTable(colors);
	
	image.fill(qRgb(180, 180, 180));
	
	int * hues = new int[image.width()];
	
	for ( int i = 0; i < image.width(); i++ )
	{
		hues[i] = i * 128 / image.width();
	}
	
	if ( highlight && highlightGradient )
	{
		float radius = .06;
		float offset = wrap(trackViews[highlightTrack].getLcbOffset(highlightLcb, highlightOffset), 0, 1);
		float lcbOffset;
		int lcb = trackViews[highlightTrack].getLcb
		(
			(offset - radius) * image.width(),
			image.width(),
			lcbOffset
		);
		RegionVector * track = (*alignment->getTracks())[getIdByTrack(highlightTrack)];
		
		int i = 0;
		
		// seek to lcb. TODO: Track method?
		//
		while ( (*track)[i]->getLcb() != lcb )
		{
			i++;
		}
		
		int delta = trackViews[highlightTrack].getRc() ? -1 : 1;
		float highlightStart = wrap((*track)[i]->getStartScaled() * delta + trackViews[highlightTrack].getOffset(), 0, 1);
		
		while ( wrap((*track)[i]->getStartScaled() * delta + trackViews[highlightTrack].getOffset(), 0, 1) < offset + radius )
		{
			const gav::Region * region = (*alignment->getLcb((*track)[i]->getLcb()).regions)[0];
			
			int start = region->getStartScaled() * image.width();
			int end = region->getEndScaled() * image.width();
			
			for ( int j = start; j <= end; j++ )
			{
				hues[j] = 60 + (wrap((*track)[i]->getStartScaled() * delta - highlightStart + trackViews[highlightTrack].getOffset(), 0, 1)) * 59 / (radius * 2);
			}
			
			i += delta;
			
			if ( i < 0 )
			{
				i += track->size();break;
			}
			else if ( i == track->size() )
			{
				i = 0;break;
			}
		}
		/*
		for ( int i = wrap(offset - radius, 0, 1) * image.width(); i <= wrap(offset + radius, 0, 1) * image.width() && i < image.width(); i++ )
		{
			int lcb = trackViews[highlightTrack].getLcb
			(
			 i,
			 image.width(),
			 lcbOffset
			 );
			if ( i < 0 )
			{
				i += image.width();
			}
			else if ( i >= image.width() )
			{
				i -= image.width();
			}
			
			int position = (int)(getRefPos(lcb, lcbOffset) * image.width());
			hues[position] = 60 + (i - (offset - radius) * image.width()) * 59 / (2 * radius * image.width());
		}*/
	}
	
	for ( int i = trackViews.size() - 1; i >= 0; i-- )
	{
		trackViews[i].draw(&image, palette, hues, progress, getTrackHeight(i), getTrackHeight(i + 1) - getTrackHeight(i), highlight, highlightLcb, highlightOffset);
	}
	
	delete [] hues;
	
	QTime time = QTime::currentTime();
	
	frames++;
	
	if ( time.second() != secLast )
	{
		//printf("fps: %d\n", frames);
		frames = 0;
	}
	
	secLast = time.second();
	
	painter.drawImage(frameWidth(), frameWidth(), image);
	
	for ( int i = 1; i < trackViews.size(); i++ )
	{
		float childSize = getTrackHeight(i + 1) - getTrackHeight(i);
		int shade;
		
		if ( childSize >= 20 )
		{
			shade = 255;
		}
		else if ( childSize < 2 )
		{
			shade = 0;
		}
		else
		{
			shade = 256 * (childSize - 2) / 18;
		}
		
		if ( i == getTrackFocus() || i == getTrackFocus() + 1 )
		{
			painter.setPen(QColor::fromRgba(qRgba(255, 255, 255, 255)));
		}
		else if ( i == getTrackHover() || i == getTrackHover() + 1 )
		{
			painter.setPen(QColor::fromRgba(qRgba(180, 180, 180, 255)));
		}
		else
		{
			painter.setPen(QColor::fromRgba(qRgba(0, 0, 0, shade)));
		}
		
		if ( shade > 0 )
		{
			painter.drawLine(frameWidth(), getTrackHeight(i) + frameWidth(), width() - frameWidth() - 1, getTrackHeight(i) + frameWidth());
		}
	}
	
	if ( highlightGradient )
	{
		float radius = .06;
		float offset = wrap(trackViews[highlightTrack].getLcbOffset(highlightLcb, highlightOffset), 0, 1);
		
		int x1 = (offset - radius) * image.width();
		int x2 = (offset + radius) * image.width();
		int y1 = getTrackHeight(highlightTrack);
		int y2 = getTrackHeight(highlightTrack + 1);
		
		QPen pen;
		pen.setWidth(3);
		pen.setColor(Qt::white);
		painter.setPen(pen);
		painter.drawRect(x1 - 1, y1 - 1, x2 - x1 + 2, y2 - y1 + 2);
	}
	
	if ( highlight )
	{
		highlightTrack = getTrackHover();
		int gap = 5;//cursorSize * .3;
		int y = cursorY;//(highlightTrack + .5) * image.height() / trackViews.size() - cursorSize / 20;
		int y1 = getTrackHeight(highlightTrack) - cursorSize / 20 + frameWidth() + 1;
		int y2 = getTrackHeight(highlightTrack + 1) + cursorSize / 20 + frameWidth() + 1;
		
		QPen pen;
		pen.setWidth(2 + cursorSize / 10);
		pen.setColor(QColor::fromHsl(120, 255, 127).rgb());
		painter.setPen(pen);
		painter.drawRect(cursorX - gap + frameWidth(), y1, gap * 2, y2 - y1);
		pen.setColor(Qt::white);
		painter.setPen(pen);
		return;
		painter.drawLine(cursorX - cursorSize, y - cursorSize, cursorX - gap, y - gap);
		painter.drawLine(cursorX - cursorSize, y + cursorSize, cursorX - gap, y + gap);
		painter.drawLine(cursorX + cursorSize, y - cursorSize, cursorX + gap, y - gap);
		painter.drawLine(cursorX + cursorSize, y + cursorSize, cursorX + gap, y + gap);
		
	}
}