Class: Sketchup::Procedure Abstract

Inherits:
Object
  • Object
show all

Overview

This class is abstract.

Implement the methods described in this class to create a procedure. Your subclass must call super from its #initialize, passing in the necessary arguments.

To create a new procedure in Ruby, you must define a new class that implements its methods.

Register the instance of your procedure class via register_procedure.

Example:

class MyProcedure < Sketchup::Procedure
  ID = 'my_company.my_extension.my_proc_id'
  DESC = 'My procedure description.'
  VERSION = 1

  def initialize
    super(id: ID, description: DESC, version: VERSION)
  end

  def validate(args)
    # Return true if valid, or an array of error hashes.
    true
  end

  def run(args)
    # Return true on success, or an array of error hashes.
  end

  def get_widget_states(args)
    # Return a hash mapping widget IDs to their desired enabled/visible states.
    {}
  end

end

my_proc = MyProcedure.new
Sketchup.register_procedure(my_proc)

Version:

  • SketchUp 2027.0

Instance Method Summary # collapse

Constructor Details

↑ #initialize(id:, description:, version:) ⇒ Object

All arguments are required.

Examples:

class MyProcedure < Sketchup::Procedure
  ID = 'my_company.my_extension.my_proc_id'
  DESC = 'My procedure description.'
  VERSION = 1

  def initialize
    super(id: ID, description: DESC, version: VERSION)
  end

  # Other required methods
end

Parameters:

  • id (String) —

    Unique identifier for this procedure. A good pattern would be something like: “company_name.extension_name.procedure_name”.

  • description (String) —

    User-facing display name of the procedure.

  • version (Integer) —

    Current version number of the procedure.

Raises:

  • (TypeError) —

    if id or description is not a String, or version is not an Integer.

  • (ArgumentError) —

    if id or description is an empty string, or a keyword argument is missing.

Version:

  • SketchUp 2027.0

Instance Method Details

↑ #declare_params_and_ui(args) ⇒ String

This method is abstract.

Called by SketchUp to get the parameter and UI declaration for this procedure.

Returns A JSON string describing the parameters and UI. The keys in the JSON object are parameter identifiers (e.g., “count”, “spacing”) that match the parameter keys used when calling ComponentDefinition#attach_procedure. Each parameter identifier maps to an object containing UI widget specifications. See the Declarative UI Schema file for the full widget schema.

Examples:

class MyProcedure < Sketchup::Procedure
  def declare_params_and_ui(args)
    count_label = 'Array count' # to be localized
    {
      "count" => {
        "widgetType" => "text",
        "valueType" => "int",
        "label" => count_label,
        "minValue" => 2
      }
    }.to_json
  end

  # Other required methods
end

Parameters:

  • args (Hash{Symbol => Object}) —

    Hash containing the method parameters.

Options Hash (args):

  • :model (Sketchup::Model) —

    The model containing the procedural component.

Returns:

  • (String) —

    A JSON string describing the parameters and UI. The keys in the JSON object are parameter identifiers (e.g., “count”, “spacing”) that match the parameter keys used when calling ComponentDefinition#attach_procedure. Each parameter identifier maps to an object containing UI widget specifications. See the Declarative UI Schema file for the full widget schema.

See Also:

Version:

  • SketchUp 2027.0

↑ #draw(args) ⇒ nil

This method is abstract.

(Optional) Called once per view refresh while the procedural component is open for editing, allowing the procedure to draw custom feedback into the view.

Note:

Since this method is called during drawing, it should run as fast as possible. Avoid slow computations and prefer simplified representations of the final geometry when possible.

Examples:

class MyProcedure < Sketchup::Procedure
  def draw(args)
    view = args[:view]
    points = args[:control_entities].grep(Sketchup::Edge).flat_map do |edge|
      [edge.start.position, edge.end.position]
    end
    view.drawing_color = 'red'
    view.line_width = 2
    view.draw(GL_LINES, points) unless points.empty?
  end

  # Other required methods
end

Parameters:

  • args (Hash{Symbol => Object}) —

    Hash containing the method parameters.

Options Hash (args):

  • :model (Sketchup::Model) —

    The model containing the procedural component.

  • :view (Sketchup::View) —

    The view to draw into.

  • :control_entities (Sketchup::Entities) —

    The input entities of the component being edited.

  • :parameters (Hash{Symbol => Integer, Float, String, Boolean}) —

    A hash of parameter identifiers (symbols) to values.

Returns:

  • (nil)

Version:

  • SketchUp 2027.0

↑ #get_extents(args) ⇒ Geom::BoundingBox

This method is abstract.

(Optional) Called while the procedural component is open for editing to get the bounds of what #draw renders. Implement this if the preview can extend beyond the bounds of the component, which could otherwise leave it clipped out of the view.

Note:

Since this method is called during drawing, it should run as fast as possible. It is strictly observational and it must not draw or modify the model.

Returns The bounds of the preview drawn by #draw. An empty bounding box means the preview needs no extra room.

Examples:

class MyProcedure < Sketchup::Procedure
  def get_extents(args)
    bounds = Geom::BoundingBox.new
    offset = [0, 0, args[:parameters][:height]]
    args[:control_entities].grep(Sketchup::Edge).each do |edge|
      bounds.add(edge.start.position, edge.end.position.offset(offset))
    end
    bounds
  end

  # Other required methods
end

Parameters:

  • args (Hash{Symbol => Object}) —

    Hash containing the method parameters.

Options Hash (args):

  • :model (Sketchup::Model) —

    The model containing the procedural component.

  • :control_entities (Sketchup::Entities) —

    The input entities of the component being edited.

  • :parameters (Hash{Symbol => Integer, Float, String, Boolean}) —

    A hash of parameter identifiers (symbols) to values.

Returns:

  • (Geom::BoundingBox) —

    The bounds of the preview drawn by #draw. An empty bounding box means the preview needs no extra room.

Version:

  • SketchUp 2027.0

↑ #get_widget_states(args) ⇒ Hash{String => Hash}

This method is abstract.

Called by SketchUp after the procedure UI is populated and after every parameter change to determine the enabled/visible state of each widget. A procedure does not need to implement this method if the widget states do not change.

Returns A hash mapping widget IDs to their desired states. Each state hash may contain :enabled and/or :visible boolean keys. Widget IDs not present in the returned hash keep their current state. See the Declarative UI Schema file for details on dynamic widget states.

Examples:

class MyProcedure < Sketchup::Procedure
  def get_widget_states(args)
    parameters = args[:parameters]
    {
      "scale" => { enabled: parameters[:count] > 2 },
      "offset" => { visible: parameters[:count] > 3 }
    }
  end

  # Other required methods
end

Parameters:

  • args (Hash{Symbol => Object}) —

    Hash containing the method parameters.

Options Hash (args):

  • :model (Sketchup::Model) —

    The model containing the procedural component.

  • :parameters (Hash{Symbol => Integer, Float, String, Boolean}) —

    The current parameter values.

Returns:

  • (Hash{String => Hash}) —

    A hash mapping widget IDs to their desired states. Each state hash may contain :enabled and/or :visible boolean keys. Widget IDs not present in the returned hash keep their current state. See the Declarative UI Schema file for details on dynamic widget states.

Version:

  • SketchUp 2027.0

↑ #on_button_clicked(args) ⇒ Symbol?

This method is abstract.

(Optional) Called when the user clicks a button widget declared in this procedure’s UI (a widget with “widgetType”: “button”). The procedure may perform arbitrary work against the model in response. A procedure does not need to implement this method if it does not declare any buttons.

Note:

If the handler modifies the model it should wrap the changes in its own operation using Model#start_operation and Model#commit_operation.

Return :reload_ui to request a full rebuild of the procedure’s UI (for example when the handler changed parameter values that the widgets need to reflect). Return nil or any other value to leave the existing widgets in place.

Examples:

class MyProcedure < Sketchup::Procedure
  def on_button_clicked(args)
    case args[:button_id]
    when "swap_type"
      current_type = args[:parameters][:curve_type].to_s
      new_type     = current_type == 'bezier' ? 'bspline' : 'bezier'
      model = args[:model]
      definition = args[:definition]
      model.start_operation('Set parameters')
      definition.set_procedure_parameters(args[:parameters].merge(curve_type: new_type))
      model.commit_operation
      :reload_ui # Rebuild the UI to reflect the changed parameter values.
    end
  end

  # Other required methods
end

Parameters:

  • args (Hash{Symbol => Object}) —

    Hash containing the method parameters.

Options Hash (args):

  • :model (Sketchup::Model) —

    The model containing the procedural component.

  • :definition (Sketchup::ComponentDefinition) —

    The definition of the procedural component.

  • :button_id (String) —

    The id of the clicked button widget.

  • :parameters (Hash{Symbol => Integer, Float, String, Boolean}) —

    The current parameter values.

Returns:

  • (Symbol, nil) —

    Return :reload_ui to request a full rebuild of the procedure’s UI (for example when the handler changed parameter values that the widgets need to reflect). Return nil or any other value to leave the existing widgets in place.

Version:

  • SketchUp 2027.0

↑ #on_open_close(args) ⇒ nil

This method is abstract.

(Optional) Called when this procedure’s component is opened or closed for editing. The :action argument distinguishes the two. This can be useful if the procedure needs to activate a custom tool when its component is opened, for instance.

Note:

This method is strictly observational. Do not modify the model from within it and do not call Model#start_operation / Model#commit_operation. It can be called while undoing or redoing an open/close and always runs inside the open/close operation.

Examples:

class MyProcedure < Sketchup::Procedure
  def on_open_close(args)
    return if args[:from_undo_redo] # Only react to direct user actions.
    case args[:action]
    when :open
      puts "Opened #{args[:definition].name}"
    when :close
      puts "Closed #{args[:definition].name}"
    end
  end

  # Other required methods
end

Parameters:

  • args (Hash{Symbol => Object}) —

    Hash containing the method parameters.

Options Hash (args):

  • :action (Symbol) —

    :open when the component was opened, :close when it was closed.

  • :from_undo_redo (Boolean) —

    true when the open or close is the result of an undo or redo, false when it is a direct user action.

  • :model (Sketchup::Model) —

    The model containing the procedural component.

  • :definition (Sketchup::ComponentDefinition) —

    The definition of the procedural component that was opened or closed.

Returns:

  • (nil)

Version:

  • SketchUp 2027.0

↑ #run(args) ⇒ Boolean, Array<Hash>

This method is abstract.

Called by SketchUp to execute the procedure.

You should first clear the output entities. Then validate the control geometry and parameters (you can call your own #validate method for this). If the input is invalid, return errors as appropriate. And finally generate the output geometry.

This method will be called with an operation already started by the framework. Do not explicitly call Model#start_operation and Model#commit_operation from within this code.

Examples:

Returning success

class MyProcedure < Sketchup::Procedure
  def run(args)
    definition = args[:definition]
    parameters = args[:parameters]
    # Clear the output geometry.
    output_entities = definition.entities
    output_entities.clear!

    # Validate definition.control_entities and parameters. Return errors if invalid.

    # Implement the procedure logic.
    true
  end

  # Other required methods
end

Returning errors

class MyProcedure < Sketchup::Procedure
  def run(args)
    [
      {
        title: "Generation Failed",
        description: "Could not generate geometry from the given input."
      }
    ]
  end

  # Other required methods
end

Parameters:

  • args (Hash{Symbol => Object}) —

    Hash containing the method parameters.

Options Hash (args):

  • :model (Sketchup::Model) —

    The model containing the procedural component.

  • :definition (Sketchup::ComponentDefinition) —

    The definition of the procedural component.

  • :parameters (Hash{Symbol => Integer, Float, String, Boolean}) —

    A hash of parameter identifiers (symbols) to values.

Returns:

  • (Boolean, Array<Hash>) —

    true on success, false on failure. Optionally, return an Array of error hashes to report specific errors. Each error hash may contain:

    • :title [String] A short title for the error.

    • :description [String] Description of the error.

    • :involved_entities [+Array<Integer>+] (optional) Persistent IDs (Entity#persistent_id) of the entities to be highlighted.

Version:

  • SketchUp 2027.0

↑ #validate(args) ⇒ Boolean, Array<Hash>

This method is abstract.

Called by SketchUp to check if the given input entities can form a valid procedural component.

Note:

Do not make model modifications within this method. Also do not call Model#start_operation and Model#commit_operation.

Returns true if valid, false if invalid. Optionally, return an Array of error hashes to report specific validation errors. Each error hash may contain:

  • :title [String] A short title for the error.

  • :description [String] Description of the error.

  • :involved_entities [+Array<Integer>+] (optional) Persistent IDs (Entity#persistent_id) of the entities to be highlighted.

Examples:

Returning success

class MyProcedure < Sketchup::Procedure
  def validate(args)
    # Implement input validation.
    true
  end

  # Other required methods
end

Returning validation errors

class MyProcedure < Sketchup::Procedure
  def validate(args)
    control_entities = args[:control_entities]
    errors = []
    if control_entities.grep(Sketchup::Face).size > 1
      pids = control_entities.grep(Sketchup::Face).map(&:persistent_id)
      errors << {
        title: "Multiple Faces",
        description: "Only a single face is allowed.",
        involved_entities: pids
      }
    end
    errors.empty? ? true : errors
  end

  # Other required methods
end

Parameters:

  • args (Hash{Symbol => Object}) —

    Hash containing the method parameters.

Options Hash (args):

  • :model (Sketchup::Model) —

    The model containing the procedural component.

  • :control_entities (Sketchup::Entities) —

    The input entities to validate.

  • :parameters (Hash{Symbol => Integer, Float, String, Boolean}) —

    A hash of parameter identifiers (symbols) to values.

Returns:

  • (Boolean, Array<Hash>) —

    true if valid, false if invalid. Optionally, return an Array of error hashes to report specific validation errors. Each error hash may contain:

    • :title [String] A short title for the error.

    • :description [String] Description of the error.

    • :involved_entities [+Array<Integer>+] (optional) Persistent IDs (Entity#persistent_id) of the entities to be highlighted.

Version:

  • SketchUp 2027.0