Edge Highlight Issue

Testing out some code to highlight edges but there is an issue highlighting an internal edge.

External view…

highlight_01

Going inside the group the internal edge in question is of course now an “external” edge so gets highlighted as expected…

highlight_02

Here’s the code…

def draw(view)
   	if @entity.is_a?(Sketchup::Edge)

		point1 = Geom::Point3d.new(@entity.start.position)
		point2 = Geom::Point3d.new(@entity.end.position)
		
		#points = [point1, point2]
		
		view.line_width = 5
		view.drawing_color = Sketchup::Color.new(40, 144, 255, 255) 

		#view.draw(GL_LINES, points)

		view.draw_lines point1, point2

	end
end

You can try and see if you get the better result when using the #draw method with a parameter openglenum : GL_LINES, GL_LINE_STRIP or GL_LINE_LOOP constants, e.g.:

view.draw(GL_LINES, point1, point2)

OR.
The #draw2d method is used to draw in screen space (using 2D screen coordinates) instead of 3D space.
But then you have to “convert” the points using the #screen_coords method to retrieve the screen coordinates of the given point on the screen.

point1_2d = view.screen_coords(point1)
point2_2d = view.screen_coords(point2)
view.draw2d(GL_LINES, point1_2d , point2_2d )

BTW
The #position method is already return Point3d, so you do not need to use the Geom::Point3d.new on it. With

point1 = @entity.start.position

you will get a Point3d


:bulb: You can get the edge vertices position into array and use this argument in a draw method

points = @entity.vertices.map(&:position)
points_2d = points.map{ |p| view.screen_coords(p) }
.
.
view.draw(GL_LINES, points)
view.draw2d(GL_LINES, points_2d)
1 Like
point1_2d = view.screen_coords(point1)
point2_2d = view.screen_coords(point2)
view.draw2d(GL_LINES, point1_2d , point2_2d )

This is good but produces some odd behaviour…

curious_01

This makes me think of some of some odd highlighting behaviour I experience with Curic’s Extend plugin - maybe they are using the #draw2d …?

It not an odd. The method is drawing onto the screen space. So it will be “above” the model 3D objects .

If you use the #line_stipple= method, and combine draw2d and draw methods then you can achieve an effect that the “hidden” part of the edge is dotted and the really visible is solid:

view.line_stipple = "."
view.draw2d(GL_LINES, point1_2d , point2_2d )
view.line_stipple = ""
view.draw(GL_LINES, point1, point2)
2 Likes

An alternative to drawing to 2D is to offset the points you draw in 3d by a little amount towards the camera.

PIXEL_OFFSET = 2
# ...
direction = view.camera.direction.reverse
offset_points = points.map { |point|
  distance = view.pixels_to_model(PIXEL_OFFSET, point)
  point.offset(direction, distance)
}
view.draw(GL_LINES, points)

For large amount of points this might be too slow, but for small amount this works wonders.

1 Like

Thanks Thomas, but I can’t seem to get this to work…

So in place of:

# ...

I put…?

point1 = Geom::Point3d.new(@entity.start.position)
point2 = Geom::Point3d.new(@entity.end.position)
points = [point1, point2]

And shouldn’t…

view.draw(GL_EDGES, points)

be…?

view.draw(GL_EDGES, offset_points)

I’m getting this error…

Error: #<ArgumentError: Cannot convert argument to Geom::Vector3d>

1 Like

Got this to work…

Changed

point.offset(distance, direction)

to

point.offset(direction, distance)

and

view.draw(GL_EDGES, points)

to

view.draw_lines offset_points
2 Likes

Oops, got my wires cross when I wrote that snippet, I didn’t have time to test it. I’ve updated my post.

That should have been GL_LINES.

Did it look better if you did the offset toward the camera?

Yes - it’s good.