Updating ConstructionLine not working/very slow

Hi everyone,

I am drawing some construction lines using
@cline = Sketchup.active_model.active_entities.add_cline(@start_position, @end_position)

Later, when the mouse is moved, I would like to update it by calling
@cline.end = @end_position.
According to the documentation this should update the end of the ConstructionLine. However, this has no effect. @cline.end will remain the same value as before.

As a workaround I create a new ConstructionLine every time the mouse is moved. But this results in janky user experience because the view will only update whenever the mouse stops.

Please help me updating the line continuously, just like the Tape Measure Tool for example.


All this is in SketchUp 2016 64bit on Windows.

Are you doing this inside a Tool instance ?

I know that on PC, whenever the mouse moves, the entire GUI is redrawn, so for example, all the menu validation procs get run. (At least last time I checked this still happened.)

If you are modifying the model each time the mouse moves, then a number of observer callback methods are getting called (in any number of other author’s extensions.) This will slow your tool down, without doubt.

Okay, the TapeMeasure tool is not using a Cline. It is drawing to the view using OpenGL calls, with a line stipple set to resemble a construction line. (View#line_stipple=)

Only after, the second click is the actual Cline added to the model’s active entities collection.

You should mimic this behavior in a tool. The view drawing methods (which only have meaning within an active tool instance,) are listed under the Sketchup::View class:
http://www.sketchup.com/intl/en/developer/docs/ourdoc/view

Hi Dan,
thanks for your tip. Works really smooth!

For completeness here’s what I did: In onMouseClick I compute @origin. In onMouseMove I compute @end_position and call view.invalidate. And here’s my draw method

def draw(view) return if @origin.nil? or @end_position.nil? view.line_stipple = '_' view.draw_lines @origin, @end_position end

One more question, though. When onMouseMove takes a while to compute (e.g. 50ms), the view won’t update until the mouse stops or I move it very slowly.
Is there a way to update the view regardless of new unprocessed mouse events? (Of course I will also look into making onMouseMove update faster)

EDIT: Nevermind, I found the issue. It was so slow because I added another object to the scene in onMouseMove If I remove that it feels responsive again. I will also have to draw this directly into the view. In order to draw a filled triangle I need to use the generic View.draw method, right?

Take note of:

View#dynamic=()
View#refresh()

Do as little as possible within this callback. Make all assignments to references that already exist (like you’re doing to instance vars.)

Either use draw_points() with a pointstyle argument of 7 (filled triangle), …

… or use draw() with GL_LINE_LOOP and 3 points for the triangle outline (with line_width= set to 1 pixel.)
Then repeat inside the outer triangle outline by say, 2 pixels, but set line_width= to 3 pixels. Repeat until your triangle is filled.