void CurveViewRange::normalize() { float xMin = m_xMin; float xMax = m_xMax; float yMin = m_yMin; float yMax = m_yMax; float newXMin = clipped((xMin+xMax)/2 - 5.3f, false); float newXMax = clipped((xMin+xMax)/2 + 5.3f, true); if (!std::isnan(newXMin) && !std::isnan(newXMax)) { m_xMin = newXMin; m_xMax = newXMax; m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax); } if (m_xMin < 0.0f) { m_xMin = -k_displayLeftMarginRatio*2.0f*5.3f; m_xMax = m_xMin + 2.0f*5.3f; } m_yAuto = false; float newYMin = clipped((yMin+yMax)/2 - 3.1f, false); float newYMax = clipped((yMin+yMax)/2 + 3.1f, true); if (!std::isnan(newYMin) && !std::isnan(newYMax)) { m_yMin = newYMin; m_yMax = newYMax; m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax); } }
void generateTriangles(unsigned short *buffer, int resolution, int x1, int y1, int x2, int y2, unsigned char *clipBuffer) { for(int y = y1; y < y2; y += lodFactor) for(int x = x1; x < x2; x += lodFactor) { int position = y * resolution + x; int f1 = position + lodFactor + resolution * lodFactor; int f2 = position; int f3 = position + resolution * lodFactor; if(!clipped(f1, f2, f3, clipBuffer)) { buffer[faceAmount++] = f1; buffer[faceAmount++] = f2; buffer[faceAmount++] = f3; } int f4 = position; int f5 = position + resolution * lodFactor + lodFactor; int f6 = position + lodFactor; if(!clipped(f1, f2, f3, clipBuffer)) { buffer[faceAmount++] = f4; buffer[faceAmount++] = f5; buffer[faceAmount++] = f6; } } }
bool clipped(int f1, int f2, int f3, unsigned char *clipBuffer) const { bool f1Clip = clipped(f1, clipBuffer); bool f2Clip = clipped(f2, clipBuffer); bool f3Clip = clipped(f3, clipBuffer); if(f1Clip && f2Clip && f3Clip) return true; return false; }
void WPiano::clipCursor() { if (!mouse_captured_) return; QRect v = viewport(); QPoint p1 = mapToGlobal(v.topLeft()); QPoint p2 = mapToGlobal(v.bottomRight()); int x = clipped(QCursor::pos().x(), p1.x(), p2.x()); int y = clipped(QCursor::pos().y(), p1.y(), p2.y()); QCursor::setPos(QPoint(x, y)); }
void operator()() const { boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } agg::path_storage ps; ps.move_to(extent_.minx(), extent_.miny()); ps.line_to(extent_.minx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.miny()); ps.close_polygon(); for (unsigned i=0;i<iterations_;++i) { for (mapnik::geometry_type & geom : paths) { poly_clipper clipped(geom,ps, agg::clipper_and, agg::clipper_non_zero, agg::clipper_non_zero, 1); clipped.rewind(0); unsigned cmd; double x,y; while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) {} } } }
void _cleanup_path(PathIterator& path, const agg::trans_affine& trans, bool remove_nans, bool do_clip, const agg::rect_base<double>& rect, e_snap_mode snap_mode, double stroke_width, bool do_simplify, bool return_curves, std::vector<double>& vertices, std::vector<npy_uint8>& codes) { typedef agg::conv_transform<PathIterator> transformed_path_t; typedef PathNanRemover<transformed_path_t> nan_removal_t; typedef PathClipper<nan_removal_t> clipped_t; typedef PathSnapper<clipped_t> snapped_t; typedef PathSimplifier<snapped_t> simplify_t; typedef agg::conv_curve<simplify_t> curve_t; transformed_path_t tpath(path, trans); nan_removal_t nan_removed(tpath, remove_nans, path.has_curves()); clipped_t clipped(nan_removed, do_clip, rect); snapped_t snapped(clipped, snap_mode, path.total_vertices(), stroke_width); simplify_t simplified(snapped, do_simplify, path.simplify_threshold()); vertices.reserve(path.total_vertices() * 2); codes.reserve(path.total_vertices()); if (return_curves) { __cleanup_path(simplified, vertices, codes); } else { curve_t curve(simplified); __cleanup_path(curve, vertices, codes); } }
bool validate() const { std::string expected_wkt("Polygon((181 286.666667,233 454,315 340,421 446,463 324,559 466,631 321.320755,631 234.386861,528 178,394 229,329 138,212 134,183 228,200 264,181 238.244444,181 286.666667),(313 190,440 256,470 248,510 305,533 237,613 263,553 397,455 262,405 378,343 287,249 334,229 191,313 190))"); boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } if (paths.size() != 1) { std::clog << "paths.size() != 1\n"; return false; } mapnik::geometry_type const& geom = paths[0]; mapnik::vertex_adapter va(geom); poly_clipper clipped(extent_, va); unsigned cmd; double x,y; mapnik::geometry_type geom2(mapnik::geometry_type::types::Polygon); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { geom2.push_vertex(x,y,(mapnik::CommandType)cmd); } std::string expect = expected_+".png"; std::string actual = expected_+"_actual.png"; auto env = mapnik::envelope(geom); if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr)) { std::clog << "generating expected image: " << expect << "\n"; render(geom2,env,expect); } render(geom2,env,actual); return benchmark::compare_images(actual,expect); }
bool operator()() const { boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } bool valid = true; for (unsigned i=0;i<iterations_;++i) { unsigned count = 0; for ( mapnik::geometry_type const& geom : paths) { mapnik::vertex_adapter va(geom); poly_clipper clipped(extent_, va); unsigned cmd; double x,y; while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { count++; } } unsigned expected_count = 31; if (count != expected_count) { std::clog << "test1: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; valid = false; } } return valid; }
std::string clip_line(mapnik::box2d<double> const& bbox, mapnik::geometry_type & geom) { using line_clipper = agg::conv_clip_polyline<mapnik::geometry_type>; line_clipper clipped(geom); clipped.clip_box(bbox.minx(),bbox.miny(),bbox.maxx(),bbox.maxy()); return dump_path(clipped); }
std::string clip_line(mapnik::box2d<double> const& bbox, mapnik::path_type const& path) { using line_clipper = agg::conv_clip_polyline<mapnik::vertex_adapter>; mapnik::vertex_adapter va(path); line_clipper clipped(va); clipped.clip_box(bbox.minx(),bbox.miny(),bbox.maxx(),bbox.maxy()); return dump_path(clipped); }
void operator() (geometry::polygon_vertex_adapter<double> & va) { using clipped_geometry_type = agg::conv_clip_polygon<geometry::polygon_vertex_adapter<double> >; using path_type = transform_path_adapter<view_transform,clipped_geometry_type>; clipped_geometry_type clipped(va); clipped.clip_box(clip_box_.minx(),clip_box_.miny(),clip_box_.maxx(),clip_box_.maxy()); path_type path(t_, clipped, prj_trans_); path.vertex(&x_,&y_); }
void CurveViewRange::roundAbscissa() { float xMin = m_xMin; float xMax = m_xMax; float newXMin = clipped(std::round((xMin+xMax)/2) - (float)Ion::Display::Width/2.0f, false); float newXMax = clipped(std::round((xMin+xMax)/2) + (float)Ion::Display::Width/2.0f-1.0f, true); if (std::isnan(newXMin) || std::isnan(newXMax)) { return; } m_xMin = newXMin; m_xMax = newXMax; if (m_xMin < 0.0f) { m_xMin = -k_displayLeftMarginRatio*(float)Ion::Display::Width; m_xMax = m_xMin+(float)Ion::Display::Width; } m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax); if (m_delegate) { m_delegate->didChangeRange(this); } }
void agg_renderer<T>::process(line_pattern_symbolizer const& sym, mapnik::feature_ptr const& feature, proj_transform const& prj_trans) { typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type; typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type; typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type; typedef agg::renderer_base<agg::pixfmt_rgba32_plain> renderer_base; typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type; typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type; agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4); agg::pixfmt_rgba32_plain pixf(buf); std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature); boost::optional<marker_ptr> mark = marker_cache::instance()->find(filename,true); if (!mark) return; if (!(*mark)->is_bitmap()) { std::clog << "### Warning only images (not '" << filename << "') are supported in the line_pattern_symbolizer\n"; return; } boost::optional<image_ptr> pat = (*mark)->get_bitmap_data(); if (!pat) return; box2d<double> ext = query_extent_ * 1.1; renderer_base ren_base(pixf); agg::pattern_filter_bilinear_rgba8 filter; pattern_source source(*(*pat)); pattern_type pattern (filter,source); renderer_type ren(ren_base, pattern); // TODO - should be sensitive to buffer size ren.clip_box(0,0,width_,height_); rasterizer_type ras(ren); //metawriter_with_properties writer = sym.get_metawriter(); for (unsigned i=0;i<feature->num_geometries();++i) { geometry_type & geom = feature->get_geometry(i); if (geom.num_points() > 1) { clipped_geometry_type clipped(geom); clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy()); path_type path(t_,clipped,prj_trans); ras.add_path(path); //if (writer.first) writer.first->add_line(path, *feature, t_, writer.second); } } }
bool Animation::update(TimingUpdateReason reason) { if (!m_timeline) return false; PlayStateUpdateScope updateScope(*this, reason, DoNotSetCompositorPending); clearOutdated(); bool idle = playStateInternal() == Idle; if (m_content) { double inheritedTime = idle || isNull(m_timeline->currentTimeInternal()) ? nullValue() : currentTimeInternal(); if (!isNull(inheritedTime)) { double timeForClipping = m_held && (!limited(inheritedTime) || isNull(m_startTime)) // Use hold time when there is no start time. ? inheritedTime // Use calculated current time when the animation is limited. : calculateCurrentTime(); if (clipped(timeForClipping)) inheritedTime = nullValue(); } // Special case for end-exclusivity when playing backwards. if (inheritedTime == 0 && m_playbackRate < 0) inheritedTime = -1; m_content->updateInheritedTime(inheritedTime, reason); } if ((idle || limited()) && !m_finished) { if (reason == TimingUpdateForAnimationFrame && (idle || hasStartTime())) { if (idle) { // TODO(dstockwell): Fire the cancel event. } else { const AtomicString& eventType = EventTypeNames::finish; if (executionContext() && hasEventListeners(eventType)) { double eventCurrentTime = currentTimeInternal() * 1000; m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, eventCurrentTime, timeline()->currentTime()); m_pendingFinishedEvent->setTarget(this); m_pendingFinishedEvent->setCurrentTarget(this); m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFinishedEvent); } } m_finished = true; } } ASSERT(!m_outdated); return !m_finished || std::isfinite(timeToEffectChange()); }
bool operator()() const { mapnik::geometry::geometry<double> geom; if (!mapnik::from_wkt(wkt_in_, geom)) { throw std::runtime_error("Failed to parse WKT"); } if (mapnik::geometry::is_empty(geom)) { std::clog << "empty geom!\n"; return false; } if (!geom.is<mapnik::geometry::polygon<double>>()) { std::clog << "not a polygon!\n"; return false; } mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom); agg::path_storage ps; ps.move_to(extent_.minx(), extent_.miny()); ps.line_to(extent_.minx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.miny()); ps.close_polygon(); bool valid = true; for (unsigned i=0;i<iterations_;++i) { unsigned count = 0; mapnik::geometry::polygon_vertex_adapter<double> va(poly); poly_clipper clipped(va,ps, agg::clipper_and, agg::clipper_non_zero, agg::clipper_non_zero, 1); clipped.rewind(0); unsigned cmd; double x,y; while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { count++; } unsigned expected_count = 31; if (count != expected_count) { std::clog << "test2: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; valid = false; } } return valid; }
bool operator()() const { mapnik::geometry::geometry<double> geom; if (!mapnik::from_wkt(wkt_in_, geom)) { throw std::runtime_error("Failed to parse WKT"); } if (mapnik::geometry::is_empty(geom)) { std::clog << "empty geom!\n"; return false; } if (!geom.is<mapnik::geometry::polygon<double>>()) { std::clog << "not a polygon!\n"; return false; } bool valid = true; for (unsigned i=0;i<iterations_;++i) { unsigned count = 0; mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom); mapnik::geometry::polygon_vertex_adapter<double> va(poly); conv_clip clipped(va); clipped.clip_box( extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy()); unsigned cmd; double x,y; // NOTE: this rewind is critical otherwise // agg_conv_adapter_vpgen will give garbage // values for the first vertex clipped.rewind(0); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { count++; } unsigned expected_count = 30; if (count != expected_count) { std::clog << "test1: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; valid = false; } } return valid; }
void createFace(unsigned short *buffer, int direction, int f1, int f2, int f3, int resolution, unsigned char *clipBuffer) { if(clipped(f1, f2, f3, clipBuffer)) return; if(direction < 0) { buffer[faceAmount++] = f1; buffer[faceAmount++] = f2; buffer[faceAmount++] = f3; } else { buffer[faceAmount++] = f2; buffer[faceAmount++] = f1; buffer[faceAmount++] = f3; } }
void operator()() const { boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } for (unsigned i=0;i<iterations_;++i) { for ( mapnik::geometry_type & geom : paths) { poly_clipper clipped(extent_, geom); unsigned cmd; double x,y; while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) {} } } }
bool validate() const { std::string expected_wkt("Polygon((212 134,329 138,394 229,528 178,631 234.4,631 321.3,559 466,463 324,421 446,315 340,233 454,181 286.7,181 238.2,200 264,183 228),(313 190,229 191,249 334,343 287,405 378,455 262,553 397,613 263,533 237,510 305,470 248,440 256))"); boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } agg::path_storage ps; ps.move_to(extent_.minx(), extent_.miny()); ps.line_to(extent_.minx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.miny()); ps.close_polygon(); if (paths.size() != 1) { std::clog << "paths.size() != 1\n"; return false; } mapnik::geometry_type const& geom = paths[0]; mapnik::vertex_adapter va(geom); poly_clipper clipped(va,ps, agg::clipper_and, agg::clipper_non_zero, agg::clipper_non_zero, 1); clipped.rewind(0); unsigned cmd; double x,y; mapnik::geometry_type geom2(mapnik::geometry_type::types::Polygon); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { geom2.push_vertex(x,y,(mapnik::CommandType)cmd); } std::string expect = expected_+".png"; std::string actual = expected_+"_actual.png"; auto env = mapnik::envelope(geom); if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr)) { std::clog << "generating expected image: " << expect << "\n"; render(geom2,env,expect); } render(geom2,env,actual); return benchmark::compare_images(actual,expect); }
bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_line_placement_clipped() { while (!geometries_to_process_.empty()) { if (geo_itr_ == geometries_to_process_.end()) { //Just processed the last geometry. Try next placement. if (!next_placement()) return false; //No more placements //Start again from begin of list geo_itr_ = geometries_to_process_.begin(); continue; //Reexecute size check } typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type; typedef coord_transform<CoordTransform,clipped_geometry_type> path_type; clipped_geometry_type clipped(**geo_itr_); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_, clipped, prj_trans_); finder_->clear_placements(); if (points_on_line_) { finder_->find_point_placements(path); } else { finder_->find_line_placements(path); } if (!finder_->get_results().empty()) { //Found a placement if (points_on_line_) { finder_->update_detector(); } geo_itr_ = geometries_to_process_.erase(geo_itr_); if (writer_.first) writer_.first->add_text( finder_->get_results(), finder_->get_extents(), feature_, t_, writer_.second); return true; } //No placement for this geometry. Keep it in geometries_to_process_ for next try. geo_itr_++; } return false; }
void Square::render(SDL_Renderer * renderer) { uint8_t a = 255; if (100 != alpha) { SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); a = alpha * 255 / 100; } SDL_SetRenderDrawColor(renderer, red, green, blue, a); if (clipped()) { SDL_Rect projection { rect.x, rect.y, clipping.w, clipping.h }; SDL_RenderFillRect(renderer, &projection); } else { SDL_RenderFillRect(renderer, &rect); } }
bool operator()() const { boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } agg::path_storage ps; ps.move_to(extent_.minx(), extent_.miny()); ps.line_to(extent_.minx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.miny()); ps.close_polygon(); bool valid = true; for (unsigned i=0;i<iterations_;++i) { unsigned count = 0; for (mapnik::geometry_type const& geom : paths) { mapnik::vertex_adapter va(geom); poly_clipper clipped(va,ps, agg::clipper_and, agg::clipper_non_zero, agg::clipper_non_zero, 1); clipped.rewind(0); unsigned cmd; double x,y; while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { count++; } } unsigned expected_count = 29; if (count != expected_count) { std::clog << "test1: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; valid = false; } } return valid; }
bool operator()() const { boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } bool valid = true; for (unsigned i=0;i<iterations_;++i) { unsigned count = 0; for (mapnik::geometry_type const& geom : paths) { mapnik::vertex_adapter va(geom); conv_clip clipped(va); clipped.clip_box( extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy()); unsigned cmd; double x,y; // NOTE: this rewind is critical otherwise // agg_conv_adapter_vpgen will give garbage // values for the first vertex clipped.rewind(0); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { count++; } } unsigned expected_count = 31; if (count != expected_count) { std::clog << "test1: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; valid = false; } } return valid; }
void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { composite_mode_e comp_op = get<composite_mode_e, keys::comp_op>(sym, feature, common_.vars_); std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_); value_bool clip = get<value_bool, keys::clip>(sym, feature, common_.vars_); value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym, feature, common_.vars_); value_double smooth = get<value_double, keys::smooth>(sym, feature, common_.vars_); value_double opacity = get<value_double, keys::opacity>(sym, feature, common_.vars_); agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); auto image_transform = get_optional<transform_type>(sym, keys::image_transform); if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform); cairo_save_restore guard(context_); context_.set_operator(comp_op); boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance().find(filename,true); if (!marker || !(*marker)) return; unsigned offset_x=0; unsigned offset_y=0; box2d<double> const& clip_box = clipping_extent(common_); pattern_alignment_enum alignment = get<pattern_alignment_enum, keys::alignment>(sym, feature, common_.vars_); if (alignment == LOCAL_ALIGNMENT) { double x0 = 0.0; double y0 = 0.0; if (feature.num_geometries() > 0) { using clipped_geometry_type = agg::conv_clip_polygon<geometry_type>; using path_type = transform_path_adapter<view_transform,clipped_geometry_type>; clipped_geometry_type clipped(feature.get_geometry(0)); clipped.clip_box(clip_box.minx(), clip_box.miny(), clip_box.maxx(), clip_box.maxy()); path_type path(common_.t_, clipped, prj_trans); path.vertex(&x0, &y0); } offset_x = std::abs(clip_box.width() - x0); offset_y = std::abs(clip_box.height() - y0); } if ((*marker)->is_bitmap()) { cairo_pattern pattern(**((*marker)->get_bitmap_data()), opacity); pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_origin(offset_x, offset_y); context_.set_pattern(pattern); } else { mapnik::rasterizer ras; image_ptr image = render_pattern(ras, **marker, image_tr, 1.0); // cairo_pattern pattern(*image, opacity); pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_origin(offset_x, offset_y); context_.set_pattern(pattern); } agg::trans_affine tr; auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform); if (geom_transform) { evaluate_transform(tr, feature, common_.vars_, *geom_transform, common_.scale_factor_); } vertex_converter<cairo_context,clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> converter(clip_box, context_,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_); if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true) converter.set<transform_tag>(); //always transform converter.set<affine_transform_tag>(); if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter for ( geometry_type & geom : feature.paths()) { if (geom.size() > 2) { converter.apply(geom); } } // fill polygon context_.set_fill_rule(CAIRO_FILL_RULE_EVEN_ODD); context_.fill(); }
void PointCloudProjector::synchronized_callback(const sensor_msgs::PointCloud2ConstPtr& points_msg, const samplereturn_msgs::PatchArrayConstPtr& patches_msg) { // create patch output message samplereturn_msgs::PatchArray positioned_patches; positioned_patches.header = patches_msg->header; positioned_patches.cam_info = patches_msg->cam_info; // create marker array debug message visualization_msgs::MarkerArray vis_markers; // create camera model object image_geometry::PinholeCameraModel model; model.fromCameraInfo(patches_msg->cam_info); // ensure tf is ready if(!listener_.canTransform(clipping_frame_id_, patches_msg->header.frame_id, patches_msg->header.stamp)) { patches_out.publish( positioned_patches ); return; } // get camera origin in clipping frame tf::StampedTransform camera; listener_.lookupTransform(clipping_frame_id_, patches_msg->header.frame_id, patches_msg->header.stamp, camera); Eigen::Vector3d camera_origin; tf::vectorTFToEigen(camera.getOrigin(), camera_origin); // scale and transform pointcloud into clipping frame pcl::PointCloud<pcl::PointXYZRGB>::Ptr colorpoints(new pcl::PointCloud<pcl::PointXYZRGB>), points_native(new pcl::PointCloud<pcl::PointXYZRGB>), points_scaled(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::fromROSMsg(*points_msg, *points_native); // this scale is a horible hack to fix the manipulator point clouds Eigen::Transform<float, 3, Eigen::Affine> trans; trans.setIdentity(); trans.scale(config_.pointcloud_scale); pcl::transformPointCloud(*points_native, *points_scaled, trans); pcl_ros::transformPointCloud(clipping_frame_id_, *points_scaled, *colorpoints, listener_); // id counter for debug markers int mid = 0; for(const auto& patch : patches_msg->patch_array) { samplereturn_msgs::Patch positioned_patch(patch); cv_bridge::CvImagePtr cv_ptr_mask; try { cv_ptr_mask = cv_bridge::toCvCopy(patch.mask, "mono8"); } catch (cv_bridge::Exception& e) { ROS_ERROR("cv_bridge mask exception: %s", e.what()); continue; } cv::Point2f roi_offset(patch.image_roi.x_offset, patch.image_roi.x_offset); Eigen::Vector4d ground_plane; // assume ground plane at z=0, in base_link xy plane for manipulators ground_plane << 0,0,1,0; float dimension, angle; tf::Stamped<tf::Point> world_point; if(samplereturn::computeMaskPositionAndSize(listener_, cv_ptr_mask->image, roi_offset, model, patches_msg->header.stamp, patches_msg->header.frame_id, ground_plane, "base_link", &dimension, &angle, &world_point, NULL)) { // if sample size is outside bounds, skip this patch if ((dimension > config_.max_major_axis) || (dimension < config_.min_major_axis)) { continue; } } // find bounding box of mask cv::Rect rect; samplereturn::computeBoundingBox(cv_ptr_mask->image, &rect); // turn image space bounding box into 4 3d rays cv::Point2d patch_origin(patch.image_roi.x_offset, patch.image_roi.y_offset); std::vector<cv::Point2d> rpoints; rpoints.push_back(cv::Point2d(rect.x, rect.y) + patch_origin); rpoints.push_back(cv::Point2d(rect.x, rect.y+rect.height) + patch_origin); rpoints.push_back(cv::Point2d(rect.x+rect.width, rect.y+rect.height) + patch_origin); rpoints.push_back(cv::Point2d(rect.x+rect.width, rect.y) + patch_origin); std::vector<Eigen::Vector3d> rays; rays.resize(rpoints.size()); std::transform(rpoints.begin(), rpoints.end(), rays.begin(), [model, patches_msg, this](cv::Point2d uv) -> Eigen::Vector3d { cv::Point3d xyz = model.projectPixelTo3dRay(uv); tf::Stamped<tf::Vector3> vect(tf::Vector3(xyz.x, xyz.y, xyz.z), patches_msg->header.stamp, patches_msg->header.frame_id); tf::Stamped<tf::Vector3> vect_t; listener_.transformVector(clipping_frame_id_, vect, vect_t); Eigen::Vector3d ray; tf::vectorTFToEigen(vect_t, ray); return ray; }); // clip point cloud by the planes of the bounding volume // described by the rays above // Add one more clipping plane at z=0 in the clipping frame // to remove noise points below the ground pcl::PointIndices::Ptr clipped(new pcl::PointIndices); for(size_t i=0;i<rays.size()+1;i++) { Eigen::Vector4f plane; if(i<rays.size()) { plane.segment<3>(0) = -rays[i].cross(rays[(i+1)%4]).cast<float>(); plane[3] = -plane.segment<3>(0).dot(camera_origin.cast<float>()); } else { plane << 0,0,1, config_.bottom_clipping_depth; } pcl::PlaneClipper3D<pcl::PointXYZRGB> clip(plane); std::vector<int> newclipped; clip.clipPointCloud3D(*colorpoints, newclipped, clipped->indices); clipped->indices.resize(newclipped.size()); std::copy(newclipped.begin(), newclipped.end(), clipped->indices.begin()); } // bail if the clipped pointcloud is empty if(clipped->indices.size() == 0) { continue; } // publish clipped pointcloud if anybody is listening if(debug_points_out.getNumSubscribers()>0) { pcl::PointCloud<pcl::PointXYZRGB> clipped_pts; pcl::ExtractIndices<pcl::PointXYZRGB> extract; extract.setInputCloud(colorpoints); extract.setIndices(clipped); extract.filter(clipped_pts); sensor_msgs::PointCloud2 clipped_msg; pcl::toROSMsg(clipped_pts, clipped_msg); debug_points_out.publish( clipped_msg ); } // compute suitable z value for this patch // First, find min, max and sum typedef std::tuple<float, float, float> stats_tuple; stats_tuple z_stats = std::accumulate( clipped->indices.begin(), clipped->indices.end(), std::make_tuple(std::numeric_limits<float>().max(), std::numeric_limits<float>().min(), 0.0f), [colorpoints](stats_tuple sum, int idx) -> stats_tuple { return std::make_tuple( std::min(std::get<0>(sum), colorpoints->points[idx].z), std::max(std::get<1>(sum), colorpoints->points[idx].z), std::get<2>(sum) + colorpoints->points[idx].z); }); // use sum to find mean float z_min = std::get<0>(z_stats); float z_max = std::get<1>(z_stats); float z_mean = std::get<2>(z_stats)/float(clipped->indices.size()); // build histogram of values larger than mean float hist_min = z_min + (z_mean-z_min)*config_.hist_min_scale; ROS_DEBUG("z_min: %04.3f z_mean: %04.3f z_max: %04.3f z_sum: %4.2f hist_min:%04.3f", z_min, z_mean, z_max, std::get<2>(z_stats), hist_min); const int NHIST = 20; int z_hist[NHIST]; bzero(z_hist, NHIST*sizeof(int)); std::accumulate(clipped->indices.begin(), clipped->indices.end(), z_hist, [colorpoints, hist_min, z_max](int *z_hist, int idx) -> int * { float z = colorpoints->points[idx].z; if(z>hist_min) { int zidx = floor((z-hist_min)*NHIST/(z_max-hist_min)); z_hist[zidx] ++; } return z_hist; }); char debughist[2048]; int pos=0; for(int i=0;i<NHIST;i++) { pos += snprintf(debughist+pos, 2048-pos, "%d, ", z_hist[i]); } debughist[pos] = '\x00'; ROS_DEBUG("hist: %s", debughist); // select the most common value larger than the mean int * argmax = std::max_element( z_hist, z_hist + NHIST ); ROS_DEBUG("argmax: %d", int(argmax - z_hist)); float z_peak = (argmax - z_hist)*(z_max - hist_min)/NHIST + hist_min; if(z_peak>config_.maximum_patch_height) { ROS_INFO("Clipping z to max, was %f", z_peak); z_peak = config_.maximum_patch_height; } // project center of patch until it hits z_peak cv::Point2d uv = cv::Point2d(rect.x + rect.width/2, rect.y + rect.height/2) + patch_origin; cv::Point3d cvxyz = model.projectPixelTo3dRay(uv); tf::Stamped<tf::Vector3> patch_ray( tf::Vector3( cvxyz.x, cvxyz.y, cvxyz.z), patches_msg->header.stamp, patches_msg->header.frame_id); tf::Stamped<tf::Vector3> clipping_ray; listener_.transformVector( clipping_frame_id_, patch_ray, clipping_ray); clipping_ray.normalize(); double r = (z_peak - camera_origin.z())/clipping_ray.z(); // finally, compute expected object position tf::Stamped<tf::Vector3> stamped_camera_origin( tf::Vector3(camera_origin.x(), camera_origin.y(), camera_origin.z()), patches_msg->header.stamp, clipping_frame_id_); tf::Vector3 object_position = stamped_camera_origin + r*clipping_ray; ROS_DEBUG_STREAM("patch_ray: (" << patch_ray.x() << ", " << patch_ray.y() << ", " << patch_ray.z() << ") "); ROS_DEBUG_STREAM("clipping_ray: (" << clipping_ray.x() << ", " << clipping_ray.y() << ", " << clipping_ray.z() << ") " << " z_peak: " << z_peak << " r: " << r); // put corresponding point_stamped in output message tf::Stamped<tf::Vector3> point( object_position, patches_msg->header.stamp, clipping_frame_id_); if(listener_.canTransform(output_frame_id_, point.frame_id_, point.stamp_)) { tf::Stamped<tf::Vector3> output_point; listener_.transformPoint(output_frame_id_, point, output_point); tf::pointStampedTFToMsg(output_point, positioned_patch.world_point); } else { tf::pointStampedTFToMsg(point, positioned_patch.world_point); } positioned_patches.patch_array.push_back(positioned_patch); if(debug_marker_out.getNumSubscribers()>0) { visualization_msgs::Marker marker; marker.id = mid++; marker.type = visualization_msgs::Marker::SPHERE; marker.action = visualization_msgs::Marker::ADD; marker.header = positioned_patch.world_point.header; marker.pose.position = positioned_patch.world_point.point; marker.scale.x = 0.02; marker.scale.y = 0.02; marker.scale.z = 0.02; marker.color.r = 0.0; marker.color.g = 0.0; marker.color.b = 1.0; marker.color.a = 1.0; vis_markers.markers.push_back(marker); } } patches_out.publish( positioned_patches ); if(debug_marker_out.getNumSubscribers()>0) { debug_marker_out.publish(vis_markers); } }
void wxNonOwnedWindow::HandleQueuedPaintRequests() { if ( m_toPaint->IsEmpty() ) return; // nothing to do if ( IsFrozen() || !IsShown() ) { // nothing to do if the window is frozen or hidden; clear the queue // and return (note that it's OK to clear the queue even if the window // is frozen, because Thaw() calls Refresh()): m_toPaint->Clear(); return; } // process queued paint requests: wxRect winRect(wxPoint(0, 0), GetSize()); wxRect paintedRect; // important note: all DCs created from now until m_isPainting is reset to // false will not update the front buffer as this flag indicates that we'll // blit the entire back buffer to front soon m_isPainting = true; int requestsCount = 0; wxRect request; while ( m_toPaint->GetNext(request) ) { requestsCount++; wxRect clipped(request); clipped.Intersect(winRect); if ( clipped.IsEmpty() ) continue; // nothing to refresh wxLogTrace(TRACE_PAINT, "%p ('%s'): processing paint request [%i,%i,%i,%i]", this, GetName().c_str(), clipped.x, clipped.y, clipped.GetRight(), clipped.GetBottom()); PaintWindow(clipped); // remember rectangle covering all repainted areas: if ( paintedRect.IsEmpty() ) paintedRect = clipped; else paintedRect.Union(clipped); } m_isPainting = false; m_toPaint->Clear(); if ( paintedRect.IsEmpty() ) return; // no painting occurred, no need to flip // Flip the surface to make the changes visible. Note that the rectangle we // flip is *superset* of the union of repainted rectangles (created as // "rectangles union" by wxRect::Union) and so some parts of the back // buffer that we didn't touch in this HandleQueuedPaintRequests call will // be copied to the front buffer as well. This is safe/correct thing to do // *only* because wx always use wxIDirectFBSurface::FlipToFront() and so // the back and front buffers contain the same data. // // Note that we do _not_ split m_toPaint into disjoint rectangles and // do FlipToFront() for each of them, because that could result in visible // updating of the screen; instead, we prefer to flip everything at once. DFBRegion r = {paintedRect.GetLeft(), paintedRect.GetTop(), paintedRect.GetRight(), paintedRect.GetBottom()}; DFBRegion *rptr = (winRect == paintedRect) ? NULL : &r; GetDfbSurface()->FlipToFront(rptr); wxLogTrace(TRACE_PAINT, "%p ('%s'): processed %i paint requests, flipped surface: [%i,%i,%i,%i]", this, GetName().c_str(), requestsCount, paintedRect.x, paintedRect.y, paintedRect.GetRight(), paintedRect.GetBottom()); }
void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym, mapnik::feature_ptr const& feature, proj_transform const& prj_trans) { typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type; typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type; typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base; typedef agg::wrap_mode_repeat wrap_x_type; typedef agg::wrap_mode_repeat wrap_y_type; typedef agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32_plain, agg::row_accessor<agg::int8u>, agg::pixel32_type> rendering_buffer; typedef agg::image_accessor_wrap<rendering_buffer, wrap_x_type, wrap_y_type> img_source_type; typedef agg::span_pattern_rgba<img_source_type> span_gen_type; typedef agg::renderer_scanline_aa<ren_base, agg::span_allocator<agg::rgba8>, span_gen_type> renderer_type; agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4); agg::pixfmt_rgba32_plain pixf(buf); ren_base renb(pixf); agg::scanline_u8 sl; ras_ptr->reset(); set_gamma_method(sym,ras_ptr); std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature); boost::optional<mapnik::marker_ptr> marker; if ( !filename.empty() ) { marker = marker_cache::instance()->find(filename, true); } else { std::clog << "### Warning: file not found: " << filename << "\n"; } if (!marker) return; if (!(*marker)->is_bitmap()) { std::clog << "### Warning only images (not '" << filename << "') are supported in the polygon_pattern_symbolizer\n"; return; } boost::optional<image_ptr> pat = (*marker)->get_bitmap_data(); if (!pat) return; unsigned w=(*pat)->width(); unsigned h=(*pat)->height(); agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)(*pat)->getBytes(),w,h,w*4); agg::span_allocator<agg::rgba8> sa; agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32_plain, agg::row_accessor<agg::int8u>, agg::pixel32_type> pixf_pattern(pattern_rbuf); img_source_type img_src(pixf_pattern); unsigned num_geometries = feature->num_geometries(); pattern_alignment_e align = sym.get_alignment(); unsigned offset_x=0; unsigned offset_y=0; if (align == LOCAL_ALIGNMENT) { double x0=0,y0=0; if (num_geometries>0) // FIXME: hmm...? { clipped_geometry_type clipped(feature->get_geometry(0)); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); path.vertex(&x0,&y0); } offset_x = unsigned(width_-x0); offset_y = unsigned(height_-y0); } span_gen_type sg(img_src, offset_x, offset_y); renderer_type rp(renb,sa, sg); //metawriter_with_properties writer = sym.get_metawriter(); for (unsigned i=0;i<num_geometries;++i) { geometry_type & geom = feature->get_geometry(i); if (geom.num_points() > 2) { clipped_geometry_type clipped(geom); clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy()); path_type path(t_,clipped,prj_trans); ras_ptr->add_path(path); //if (writer.first) writer.first->add_polygon(path, *feature, t_, writer.second); } } agg::render_scanlines(*ras_ptr, sl, rp); }
Py::Object _path_module::convert_path_to_polygons(const Py::Tuple& args) { typedef agg::conv_transform<PathIterator> transformed_path_t; typedef PathNanRemover<transformed_path_t> nan_removal_t; typedef PathClipper<nan_removal_t> clipped_t; typedef PathSimplifier<clipped_t> simplify_t; typedef agg::conv_curve<simplify_t> curve_t; typedef std::vector<double> vertices_t; args.verify_length(4); PathIterator path(args[0]); agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false); double width = Py::Float(args[2]); double height = Py::Float(args[3]); bool do_clip = width != 0.0 && height != 0.0; bool simplify = path.should_simplify(); transformed_path_t tpath(path, trans); nan_removal_t nan_removed(tpath, true, path.has_curves()); clipped_t clipped(nan_removed, do_clip, width, height); simplify_t simplified(clipped, simplify, path.simplify_threshold()); curve_t curve(simplified); Py::List polygons; vertices_t polygon; double x, y; unsigned code; polygon.reserve(path.total_vertices() * 2); while ((code = curve.vertex(&x, &y)) != agg::path_cmd_stop) { if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) { if (polygon.size() >= 2) { polygon.push_back(polygon[0]); polygon.push_back(polygon[1]); _add_polygon(polygons, polygon); } polygon.clear(); } else { if (code == agg::path_cmd_move_to) { _add_polygon(polygons, polygon); polygon.clear(); } polygon.push_back(x); polygon.push_back(y); } } _add_polygon(polygons, polygon); return polygons; }
bool validate() const { mapnik::geometry::geometry<double> geom; if (!mapnik::from_wkt(wkt_in_, geom)) { throw std::runtime_error("Failed to parse WKT"); } if (mapnik::geometry::is_empty(geom)) { std::clog << "empty geom!\n"; return false; } if (!geom.is<mapnik::geometry::polygon<double>>()) { std::clog << "not a polygon!\n"; return false; } mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom); mapnik::geometry::polygon_vertex_adapter<double> va(poly); conv_clip clipped(va); clipped.clip_box( extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy()); clipped.rewind(0); mapnik::geometry::polygon<double> poly2; mapnik::geometry::linear_ring<double> ring; // exterior ring unsigned cmd; double x, y, x0, y0; while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { if (cmd == mapnik::SEG_MOVETO) { x0 = x; y0 = y; } if (cmd == mapnik::SEG_CLOSE) { ring.emplace_back(x0, y0); break; } ring.emplace_back(x,y); } poly2.push_back(std::move(ring)); // interior rings ring.clear(); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { if (cmd == mapnik::SEG_MOVETO) { x0 = x; y0 = y; } else if (cmd == mapnik::SEG_CLOSE) { ring.emplace_back(x0,y0); poly2.push_back(std::move(ring)); ring.clear(); continue; } ring.emplace_back(x,y); } std::string expect = expected_+".png"; std::string actual = expected_+"_actual.png"; mapnik::geometry::multi_polygon<double> mp; mp.emplace_back(poly2); auto env = mapnik::geometry::envelope(mp); if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr)) { std::clog << "generating expected image: " << expect << "\n"; render(mp,env,expect); } render(mp,env,actual); return benchmark::compare_images(actual,expect); }
Py::Object _path_module::convert_to_svg(const Py::Tuple& args) { args.verify_length(5); PathIterator path(args[0]); agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false); Py::Object clip_obj = args[2]; bool do_clip; agg::rect_base<double> clip_rect(0, 0, 0, 0); if (clip_obj.isNone() || !clip_obj.isTrue()) { do_clip = false; } else { double x1, y1, x2, y2; Py::Tuple clip_tuple(clip_obj); x1 = Py::Float(clip_tuple[0]); y1 = Py::Float(clip_tuple[1]); x2 = Py::Float(clip_tuple[2]); y2 = Py::Float(clip_tuple[3]); clip_rect.init(x1, y1, x2, y2); do_clip = true; } bool simplify; Py::Object simplify_obj = args[3]; if (simplify_obj.isNone()) { simplify = path.should_simplify(); } else { simplify = simplify_obj.isTrue(); } int precision = Py::Int(args[4]); #if PY_VERSION_HEX < 0x02070000 char format[64]; snprintf(format, 64, "%s.%dg", "%", precision); #endif typedef agg::conv_transform<PathIterator> transformed_path_t; typedef PathNanRemover<transformed_path_t> nan_removal_t; typedef PathClipper<nan_removal_t> clipped_t; typedef PathSimplifier<clipped_t> simplify_t; transformed_path_t tpath(path, trans); nan_removal_t nan_removed(tpath, true, path.has_curves()); clipped_t clipped(nan_removed, do_clip, clip_rect); simplify_t simplified(clipped, simplify, path.simplify_threshold()); size_t buffersize = path.total_vertices() * (precision + 5) * 4; char* buffer = (char *)malloc(buffersize); char* p = buffer; const char codes[] = {'M', 'L', 'Q', 'C'}; const int waits[] = { 1, 1, 2, 3}; int wait = 0; unsigned code; double x = 0, y = 0; while ((code = simplified.vertex(&x, &y)) != agg::path_cmd_stop) { if (wait == 0) { *p++ = '\n'; if (code == 0x4f) { *p++ = 'z'; *p++ = '\n'; continue; } *p++ = codes[code-1]; wait = waits[code-1]; } else { *p++ = ' '; } #if PY_VERSION_HEX >= 0x02070000 char* str; str = PyOS_double_to_string(x, 'g', precision, 0, NULL); p += snprintf(p, buffersize - (p - buffer), str); PyMem_Free(str); *p++ = ' '; str = PyOS_double_to_string(y, 'g', precision, 0, NULL); p += snprintf(p, buffersize - (p - buffer), str); PyMem_Free(str); #else char str[64]; PyOS_ascii_formatd(str, 64, format, x); p += snprintf(p, buffersize - (p - buffer), str); *p++ = ' '; PyOS_ascii_formatd(str, 64, format, y); p += snprintf(p, buffersize - (p - buffer), str); #endif --wait; } #if PY3K PyObject* result = PyUnicode_FromStringAndSize(buffer, p - buffer); #else PyObject* result = PyString_FromStringAndSize(buffer, p - buffer); #endif free(buffer); return Py::Object(result, true); }