IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    GPv3 and Curves API Familiarization Notes

    吴奕茗 (chengdulittlea@outlook.com)发表于 2023-12-29 20:55:34
    love 0

    GPv3 and Curves API Familiarization Notes

    {read_more}

    // A typical operator exec call...
    
    static int grease_pencil_do_whatever(bContext *C, wmOperator * /*op*/)
    {
      const Scene *scene = CTX_data_scene(C);
      Object *object = CTX_data_active_object(C);
      GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
    
    
      // How to get "drawings" to edit under GPv3 and iterate over each "drawing":
    
      const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
    
      threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
        IndexMaskMemory memory;
        const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
            *object, info.drawing, memory);
        if (strokes.is_empty()) {
          return;
        }
    
    
        // Get a curves container to work on inside this drawing... By using
        // &curves allows us to later just directly assign a new one. So this way
        // we could create new curves easier.
        // 
        // Essentially we don't "edit" the curve, but creates a new one, and there
        // are utility functions in `Curves` to allow easy transferring of old data.
    
        bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
    
    
        // And choose to work with "Select Domain"...
    
        const bke::AttrDomain selection_domain = ED_grease_pencil_selection_domain_get(
          scene->toolsettings);
    
        if (selection_domain == bke::AttrDomain::Curve) {
          curves.remove_curves(elements, {});
        }
        else if (selection_domain == bke::AttrDomain::Point) {
          curves = remove_points_and_split(curves, elements);
        }
    
    
        // Curves etc...
    
        Array<bool> points_to_delete(curves.points_num()); // 1d array
        const int total_points = points_to_delete.as_span().count(false);
    
    
        // This is how we iterate over curves...
    
        for (const int curve_i : curves.curves_range()) {
          const IndexRange points = points_by_curve[curve_i];
          const Span<bool> curve_points_to_delete = points_to_delete.as_span().slice(points);
          const bool curve_cyclic = src_cyclic[curve_i];
          //...
        }
    
      }); // End parallel iteration over stroke.
    
    
      // Create a new curves "container", this is where we actually create new stuff and
      // then we put in data...
      // If we have counts for individual curves, counts can be accumulated into new offsets
      // with convenience functions.
    
      bke::CurvesGeometry dst_curves(total_points, total_curves);
    
      MutableSpan<int> new_curve_offsets = dst_curves.offsets_for_write();
      array_utils::copy(dst_curve_counts.as_span(), new_curve_offsets.drop_back(1));
      offset_indices::accumulate_counts_to_offsets(new_curve_offsets);
    
      bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
      const bke::AttributeAccessor src_attributes = curves.attributes();
    
    
      // Copy from dst-src matching pairs if data is modified from previous curves.
    
      /* Transfer curve attributes. */
      gather_attributes(
          src_attributes, bke::AttrDomain::Curve, {}, {"cyclic"}, dst_to_src_curve, dst_attributes);
      array_utils::copy(dst_cyclic.as_span(), dst_curves.cyclic_for_write());
    
    
      // Individual elements delivered by `Span` and `Array` etc can all be accessed with [].
      // So `MutableSpan some=other; some[index]=thing;` is valid.
    }
    2023/12/29 20:03:29 - 2023/12/29 20:55:34


沪ICP备19023445号-2号
友情链接