SegmentRef Script::dereference(reg_t pointer) { if (pointer.getOffset() > _buf->size()) { error("Script::dereference(): Attempt to dereference invalid pointer %04x:%04x into script %d segment (script size=%u)", PRINT_REG(pointer), _nr, _buf->size()); return SegmentRef(); } SegmentRef ret; ret.isRaw = true; ret.maxSize = _buf->size() - pointer.getOffset(); ret.raw = _buf->getUnsafeDataAt(pointer.getOffset(), ret.maxSize); return ret; }
SegmentRef SegmentObj::dereference(reg_t pointer) { error("Error: Trying to dereference pointer %04x:%04x to inappropriate segment", PRINT_REG(pointer)); return SegmentRef(); }
bool SegmentTulipDepth::run(Communicator *comm, const Options &options, ShapeGraph &map, bool simple_version) { AttributeTable &attributes = map.getAttributeTable(); std::string stepdepth_col_text = "Angular Step Depth"; int stepdepth_col = attributes.insertOrResetColumn(stepdepth_col_text.c_str()); // The original code set tulip_bins to 1024, divided by two and added one // in order to duplicate previous code (using a semicircle of tulip bins) size_t tulip_bins = 513; std::vector<bool> covered(map.getConnections().size()); for (size_t i = 0; i < map.getConnections().size(); i++) { covered[i] = false; } std::vector<std::vector<SegmentData> > bins(tulip_bins); int opencount = 0; for (auto& sel: map.getSelSet()) { int row = depthmapX::getMapAtIndex(map.getAllShapes(), sel)->first; if (row != -1) { bins[0].push_back(SegmentData(0,row,SegmentRef(),0,0.0,0)); opencount++; } } int depthlevel = 0; auto binIter = bins.begin(); int currentbin = 0; while (opencount) { while (binIter->empty()) { depthlevel++; binIter++; currentbin++; if (binIter == bins.end()) { binIter = bins.begin(); } } SegmentData lineindex; if (binIter->size() > 1) { // it is slightly slower to delete from an arbitrary place in the bin, // but it is necessary to use random paths to even out the number of times through equal paths int curr = pafrand() % binIter->size(); auto currIter = binIter->begin() + curr; lineindex = *currIter; binIter->erase(currIter); // note: do not clear choice values here! } else { lineindex = binIter->front(); binIter->pop_back(); } opencount--; if (!covered[lineindex.ref]) { covered[lineindex.ref] = true; Connector& line = map.getConnections()[lineindex.ref]; // convert depth from tulip_bins normalised to standard angle // (note the -1) double depth_to_line = depthlevel / ((tulip_bins - 1) * 0.5); map.getAttributeRowFromShapeIndex(lineindex.ref).setValue(stepdepth_col,depth_to_line); register int extradepth; if (lineindex.dir != -1) { for (auto& segconn: line.m_forward_segconns) { if (!covered[segconn.first.ref]) { extradepth = (int) floor(segconn.second * tulip_bins * 0.5); auto currIter = binIter; bins[(currentbin + tulip_bins + extradepth) % tulip_bins].push_back( SegmentData(segconn.first,lineindex.ref,lineindex.segdepth+1,0.0,0)); opencount++; } } } if (lineindex.dir != 1) { for (auto& segconn: line.m_back_segconns) { if (!covered[segconn.first.ref]) { extradepth = (int) floor(segconn.second * tulip_bins * 0.5); bins[(currentbin + tulip_bins + extradepth) % tulip_bins].push_back( SegmentData(segconn.first,lineindex.ref,lineindex.segdepth+1,0.0,0)); opencount++; } } } } } map.setDisplayedAttribute(-2); // <- override if it's already showing map.setDisplayedAttribute(stepdepth_col); return true; }
bool SegmentAngular::run(Communicator *comm, const Options &options, ShapeGraph &map, bool simple_version) { if (map.getMapType() != ShapeMap::SEGMENTMAP) { return false; } AttributeTable &attributes = map.getAttributeTable(); time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, map.getConnections().size()); } // note: radius must be sorted lowest to highest, but if -1 occurs ("radius n") it needs to be last... // ...to ensure no mess ups, we'll re-sort here: bool radius_n = false; std::vector<double> radii; for (double radius : options.radius_set) { if (radius < 0) { radius_n = true; } else { radii.push_back(radius); } } if (radius_n) { radii.push_back(-1.0); } std::vector<int> depth_col, count_col, total_col; // first enter table values for (int radius : radii) { std::string radius_text = makeRadiusText(Options::RADIUS_ANGULAR, radius); std::string depth_col_text = std::string("Angular Mean Depth") + radius_text; attributes.insertOrResetColumn(depth_col_text.c_str()); std::string count_col_text = std::string("Angular Node Count") + radius_text; attributes.insertOrResetColumn(count_col_text.c_str()); std::string total_col_text = std::string("Angular Total Depth") + radius_text; attributes.insertOrResetColumn(total_col_text.c_str()); } for (int radius : radii) { std::string radius_text = makeRadiusText(Options::RADIUS_ANGULAR, radius); std::string depth_col_text = std::string("Angular Mean Depth") + radius_text; depth_col.push_back(attributes.getColumnIndex(depth_col_text.c_str())); std::string count_col_text = std::string("Angular Node Count") + radius_text; count_col.push_back(attributes.getColumnIndex(count_col_text.c_str())); std::string total_col_text = std::string("Angular Total Depth") + radius_text; total_col.push_back(attributes.getColumnIndex(total_col_text.c_str())); } std::vector<bool> covered(map.getShapeCount()); size_t i = 0; for (auto & iter : attributes){ for (size_t j = 0; j < map.getShapeCount(); j++) { covered[j] = false; } std::vector<std::pair<float, SegmentData>> anglebins; anglebins.push_back(std::make_pair(0.0f, SegmentData(0, i, SegmentRef(), 0, 0.0, 0))); std::vector<double> total_depth; std::vector<int> node_count; for (size_t r = 0; r < radii.size(); r++) { total_depth.push_back(0.0); node_count.push_back(0); } // node_count includes this one, but will be added in next algo: while (anglebins.size()) { auto iter = anglebins.begin(); SegmentData lineindex = iter->second; if (!covered[lineindex.ref]) { covered[lineindex.ref] = true; double depth_to_line = iter->first; total_depth[lineindex.coverage] += depth_to_line; node_count[lineindex.coverage] += 1; anglebins.erase(iter); Connector &line = map.getConnections()[lineindex.ref]; if (lineindex.dir != -1) { for (auto &segconn : line.m_forward_segconns) { if (!covered[segconn.first.ref]) { double angle = depth_to_line + segconn.second; int rbin = lineindex.coverage; while (rbin != radii.size() && radii[rbin] != -1 && angle > radii[rbin]) { rbin++; } if (rbin != radii.size()) { depthmapX::insert_sorted( anglebins, std::make_pair(float(angle), SegmentData(segconn.first, SegmentRef(), 0, 0.0, rbin))); } } } } if (lineindex.dir != 1) { for (auto &segconn : line.m_back_segconns) { if (!covered[segconn.first.ref]) { double angle = depth_to_line + segconn.second; int rbin = lineindex.coverage; while (rbin != radii.size() && radii[rbin] != -1 && angle > radii[rbin]) { rbin++; } if (rbin != radii.size()) { depthmapX::insert_sorted( anglebins, std::make_pair(float(angle), SegmentData(segconn.first, SegmentRef(), 0, 0.0, rbin))); } } } } } else { anglebins.erase(iter); } } AttributeRow &row = iter.getRow(); // set the attributes for this node: int curs_node_count = 0; double curs_total_depth = 0.0; for (size_t r = 0; r < radii.size(); r++) { curs_node_count += node_count[r]; curs_total_depth += total_depth[r]; row.setValue(count_col[r], float(curs_node_count)); if (curs_node_count > 1) { // note -- node_count includes this one -- mean depth as per p.108 Social Logic of Space double mean_depth = curs_total_depth / double(curs_node_count - 1); row.setValue(depth_col[r], float(mean_depth)); row.setValue(total_col[r], float(curs_total_depth)); } else { row.setValue(depth_col[r], -1); row.setValue(total_col[r], -1); } } // if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, i); } } i++; } map.setDisplayedAttribute(-2); // <- override if it's already showing map.setDisplayedAttribute(depth_col.back()); return true; }