I was thinking of using a texture in one of my tools but after testing out this method it seems to really hang SketchUp and only slightly works:
Does anyone have any experience or thoughts on using this method in a tool in their extension?
I was thinking of using a texture in one of my tools but after testing out this method it seems to really hang SketchUp and only slightly works:
Does anyone have any experience or thoughts on using this method in a tool in their extension?
There was a discussion here a while ago about using a tool texture to draw floating buttons that the user could click on. (Search the category.)
Otherwise, your “slightly works” and “thinking of using a texture” are somewhat vague.
What did the test entail?
Sorry, I didn’t provide more details.
With my plugins I usually like to provide a wireframe or some other form of geometry to help indicate what the plugin(s) will end up drawing. Previously they were always just wireframes, then I started adding in shaded polygons to provide even more visual information to the user (see example below):
However, after a bit of testing I find it to be a bit unstable (not as robust as i would like). I am just trying to see if anyone else has tried using this method in a similar fashion and what their mileage has been.
If they have found it to be useful, what hints or caveats should I be aware of. It seems fairly new, only introduced since 2018 or perhaps 2020.
In this particular case I want to use a texture with my new floor plugin when drawing a floor from a face. With the texture I can possibly create an image that shows the direction of the floor joists (ie. straight lines), at least that is the idea. This would theoretically be much more lightweight than trying to pre-calculate where all those floor joists will be within the draw tool.
In what way(s) ?
Z-fighting with the underlying face?
Flashing texture?
Slow (not keeping up with the cursor)?
Perhaps it needs to be drawn slightly above the face?
I need to test it further but when I try out my test tool, it doesn’t show the face with the texture until I zoom in our out, which I find a bit strange.
Graphics glitches may occur in tools if not invalidating the view at the proper time (place in code.)
Have you checked the Issue Tracker to see if this is a known bug?
Does it occur with both graphic engines? … or only one?
I’ve only tested it in SU 2023.
Here is my very simple code, most copied from the documentation linked above:
module Example
class MyTool
def activate
view = Sketchup.active_model.active_view
# image_rep = view.model.materials.current.texture.image_rep
@thisdir = 'C:/Users/Administrator/AppData/Roaming/SketchUp/SketchUp 2017/SketchUp/Plugins/medeek_floor_ext/materials/BRICK_RED.jpg'
image_rep = Sketchup::ImageRep.new(@thisdir)
@texture_id = view.load_texture(image_rep)
end
def deactivate(view)
view.release_texture(@texture_id)
end
def draw(view)
points = [ [0, 0, 0], [9, 0, 0], [9, 9, 0], [0, 9, 0] ]
uvs = [ [0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0] ]
view.draw(GL_QUADS, points, texture: @texture_id, uvs: uvs)
end
end
end
Sketchup.active_model.select_tool(Example::MyTool.new)
I’ll test it after supper. (I’ll need to tweak the texture path and copy one of the native textures.)
But the 1st thing I see is that the points
and uvs
arrays are not changing in the test, and should be defined in an @var
either in the activate()
or initialize()
methods of the tool object. Ie, they are redefined each and every time the view is invalidated and the SketchUp engine calls the draw()
method.
Second thing is I see no call to view.invalidate
at all. Normally there would be a call at the end of the activate
, deactivate
, suspend
and resume
methods.
Okay, … no, it is not strange. As I said your tool code must tell the SketchUp graphics engine when it is time to refresh the view, either to show tool drawing or erase it. In addition, the SketchUp engine will decide upon other actions (such as zooming in & out) when to refresh the view.
This is “Tools 101” to use an educational metaphor.
This example allows you to see the difference without and with view.invalidate
calls.
module Example
class MyTool
def initialize(refresh = false)
@refresh = refresh
@points = [ [0, 0, 0], [9, 0, 0], [9, 9, 0], [0, 9, 0] ]
@uvs = [ [0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0] ]
end
def activate
view = Sketchup.active_model.active_view
@thisdir = File.join(
ENV["APPDATA"],
'SketchUp/SketchUp 2017/SketchUp/Plugins/medeek_floor_ext/materials/'
)
#@thisdir = "D:/DOCUMENTS/SketchUp/Images/Textures"
texture = UI.openpanel(
"Choose Texture File", @thisdir, "Image Files|*.jpg;*.png;||"
)
Sketchup.active_model.select_tool(nil) unless texture
image_rep = Sketchup::ImageRep.new(texture)
@texture_id = view.load_texture(image_rep)
view.invalidate if @refresh
end
def deactivate(view)
view.release_texture(@texture_id)
view.invalidate if @refresh
end
def resume(view)
view.invalidate if @refresh
end
def suspend(view)
view.invalidate if @refresh
end
def draw(view)
view.draw(GL_QUADS, @points, texture: @texture_id, uvs: @uvs)
end
end
unless defined?(@loaded)
menu = UI.menu('Plugins').add_submenu('Test Texture Tool')
menu.add_item('No refresh') {
Sketchup.active_model.select_tool(Example::MyTool.new)
}
menu.add_item('With Refresh') {
Sketchup.active_model.select_tool(Example::MyTool.new(true))
}
@loaded = true
end
end
So when your tool does not make the invalidate calls, I see what you see. Often the texture is not drawn. And scrolling the mouse wheel to zoom causes a view refresh and the texture shows.
This is basically “pilot error”. By now you aught to have a code template for a tool object with the draw
method blank but prototypes for the activate
, deactivate
, suspend
and resume
methods containing calls to view.invalidate
.
The calls for refreshing in suspend
and resume
are so that during view manipulation tools (Orbit, Pan, etc.,) that the tool’s drawing is erased and redrawn respectively.