Thank you for your codes but I have 2 problems. 1- cannot change transparency of backside of box. 2- Transparency change from outside not both outside and inside. Next time for codes I will follow your advice.
f.material = mat
f.back_material = mat
?
unfortunately f.back_material = mat cannot work.
How doesn’t it work.
A face has a .material
and a .back_material
- both of which can be changed in code…
Please explain your problem more clearly…
following code works.
faces.each{|f|
f.material = mat
}
faces.each{|f|
f.back_material = mat
}
I try to “summarizing” the help from TIG for you
Your onLButtonDown
method should look like this:
def onLButtonDown(flags, x, y, view)
mod = Sketchup.active_model
sel = mod.selection
# select face
input = Sketchup::InputPoint.new
input.pick view, x, y
face2 = input.face
if face2
mats=Sketchup.active_model.materials
mat=mats.add("MyMatName") unless mat=mats["MyMatName"] # or another name
mat.alpha=0.5 # or other transparency
faces=[]
edges=face2.edges
edges.each{|e|
faces << e.faces
}
faces.flatten!
faces.uniq!
faces.each{|f|
f.material = mat
f.back_material = mat
}
else
view.model.active_path = input.instance_path.valid? ? input.instance_path : nil
end
end
You are so clever!!! It works but still I have other problem. When we select one side of a box, all other sides of box will be transparency except opposite side. (opposite side is not connected to face directly). How can I change transparency of all sides of box?
Something like this:
References
References:
Face#all_connected-instance_method
Vector3d#parallel-instance_method
Face.normal-instance_method
def onLButtonDown(flags, x, y, view)
mod = Sketchup.active_model
sel = mod.selection
# select face
input = Sketchup::InputPoint.new
input.pick view, x, y
face2 = input.face
if face2
mats=Sketchup.active_model.materials
mat=mats.add("MyMatName") unless mat=mats["MyMatName"] # or another name
mat.alpha=0.5 # or other transparency
connected = face2.all_connected
faces = connected.grep(Sketchup::Face)
faces.each{|f|
#this will make transparent the face2 and opposite face
if f.normal.parallel?(face2.normal) # you can take out this condition if want all faces transparent
f.material = mat
f.back_material = mat
end # you can take out this condition if want all faces transparent
}
else
view.model.active_path = input.instance_path.valid? ? input.instance_path : nil
end
end
It works really good and my problem completely solved. Thank you so much. Is it possible first we select group and change group transparency or we have to change material of faces as you did?
Administrative note : Please do not quote my full post just above your answer!
def onLButtonDown(flags, x, y, view)
mod = Sketchup.active_model # this line not in use in this code
sel = mod.selection # this line not in use in this code
# select face
input = Sketchup::InputPoint.new
input.pick view, x, y
face2 = input.face
# prints the instance path to Ruby console.
# CHECK THIS OUT yourself what you see in console when you clicks
p input.instance_path.to_a
if face2
mats=Sketchup.active_model.materials
mat=mats.add("MyMatName") unless mat=mats["MyMatName"] # or another name
mat.alpha=0.5 # or other transparency
path = input.instance_path.to_a
gr = path.grep(Sketchup::Group).first
gr.material = mat if gr
#this is now may obsolete below here:
# else
#view.model.active_path = input.instance_path.valid? ? input.instance_path : nil
end
end
Your codes are really good and simply I can use it in my own plugins. Please forgive me to bother you again. I wish to pick material from face2, change its transparency and color and at the end return it to its original material. Can you help me for it?
Here we are. Try and find out how and why it works.
You must find the “right” face to click to get the color/transparency change effect!
In a return, I would like to ask you to find the description:
of the view.draw_text
instance method,
as well as the Color class
description
in a Ruby API documentation and copy-paste a link for me.
module Majid866
module Test
class Box
def activate
# note the variable start with '@', meaning
# it is 'exposed' to other methods
# within this class instance
# in other words this is instance variable
# so we can, and will use it e.g. in onLButtonDown method
mod = Sketchup.active_model
sel = mod.selection #not used
ent = mod.active_entities
#Make a group
pt1 = [0, 0, 0]
pt2 = [2, 0, 0]
pt3 = [2, 10, 0]
pt4 = [0, 10, 0]
grp = mod.active_entities.add_group
@face1 = grp.entities.add_face [pt1, pt2, pt3, pt4]
# add a "built in" Color object to face to be able see differences
# ( face.material method accept it as material )
@face1.material = "HotPink"
@face1.back_material = "HotPink"
@face1.pushpull -10
#Define a material with color transparency for later use
mats = Sketchup.active_model.materials
@mat = mats.add("MyMaterial") unless @mat = mats["MyMaterial"] # or another name
#add color
@mat.color = "Dodgerblue" # or other color
#add transparency
@mat.alpha = 0.5 # or other transparency
#define a status of the tool
@state = 1
#define a "status" text initial value
@face_is_what_we_want = "Click on the right face!"
end
def deactivate(view)
view.invalidate
end
def onLButtonDown(flags, x, y, view)
# use some InputPoint methods to see if the cursor on face
input = Sketchup::InputPoint.new
input.pick view, x, y
face2 = input.face
# The InputPoint#face method will return a Sketchup::Face object OR nil
# boolean check will return false if it is nil, or true if it is some face
# So, we can test if the cursor is over some face
# then if we get true then we will deal with it
# the second condition is checking if the picked face2
# is the same as we first created in the activate method
if face2 && face2 == @face1
# Check the status
case @state
when 1
# retrieve and store the material
@original_mat = face2.material
# change the face2 material to your above defined material
face2.material = @mat
face2.back_material = @mat #optional
# Change a status of the tool, so your next click will
# "land" in state 2 condition
@state = 2
when 2
face2.material = @original_mat
face2.back_material = @original_mat #optional
# Change a status of the tool back to 1
# so you can click and click "forever"
@state = 1
end #case
#set the "status" text if we are on a right face
@face_is_what_we_want = "You are Smart. Click again"
else
#set the wrong "status" text if we are on a wrong face
@face_is_what_we_want = "Ups! Try again to click on the right face!"
end #if
view.invalidate
end
#Print out to screen upper left
def draw(view)
view.draw_text( [10,10], @face_is_what_we_want )
end
end # Class
end # module Test
end # module Majid866
It would be appropriate to wrap the Box class inside a uniquely named module. As is, the Box class is created directly in the global namespace.
It has been told many times… but he do not get it.
I hope he will use this only his own and will wrap in later… anyway I edited.
I wanted to help him to get some basic.
Sorry to bother you again. I will follow your advice and will try for improvement. I used your code in following example I supposed in second click, box color will be red (Original color) but it change to white!!! Can you help me to find problem?
module Majid866
UI.menu("Plugins").add_item("Box") {
Sketchup.active_model.select_tool(Box.new)
}
class Box
def activate
mod = Sketchup.active_model
sel = mod.selection
ent = mod.active_entities
#Make a group
pt1 = [0, 0, 0]
pt2 = [2, 0, 0]
pt3 = [2, 10, 0]
pt4 = [0, 10, 0]
@st = 0
grp = Sketchup.active_model.active_entities.add_group
face1 = grp.entities.add_face [pt1, pt2, pt3, pt4]
face1.pushpull -10
grp.material = "red"
end
def deactivate(view)
view.invalidate
end
def onLButtonDown(flags, x, y, view)
if @st == 0
input = Sketchup::InputPoint.new
input.pick view, x, y
face2 = input.face
if face2
@st += 1
@original_mat = face2.material # Should be red if click on box
mats = Sketchup.active_model.materials
mat = mats.add("green") unless mat = mats["green"] # or another name
mat.alpha = 0.2 # or other transparency
path = input.instance_path.to_a
@gr = path.grep(Sketchup::Group).first
@gr.material = mat if @gr
end
else
@st = 0
@gr.material = @original_mat #
end
end
end
end
I know my problem and it was my plan to review all after solving this problem. I plan to use this example in a bigger plugins and it is why I use variables the way that make no sense. for example I know in second click I can select group again but in my final codes, I will make a hole in box and second click cannot find group. Let me keep instance variables for further uses.
You have been applied a material to the group. The faces still have the default “white” material.
Please check it “manually”. I mean draw a box in SU - without Ruby code - put into group, apply material to group and double click to edit. If you select the face you will see what I described above.
Therefore when you are queering the face.material
you will get the “white” not red!
If you check my previous code you can see I applied material to face with this “special” purpose!
You are good teacher. I need time to review all codes and have better understanding. After many tries also I find out difference between group material and face material and solve problem by following codes although I didn’t know why but I feel shy to ask you. I am so happy you told me reason. Thank you.
module Majid866
UI.menu("Plugins").add_item("Box") {
Sketchup.active_model.select_tool(Box.new)
}
class Box
def activate
mod = Sketchup.active_model
sel = mod.selection
ent = mod.active_entities
#Make a group
pt1 = [0, 0, 0]
pt2 = [2, 0, 0]
pt3 = [2, 10, 0]
pt4 = [0, 10, 0]
@st = 0
grp = Sketchup.active_model.active_entities.add_group
face1 = grp.entities.add_face [pt1, pt2, pt3, pt4]
face1.pushpull -10
grp.material = "red"
end
def deactivate(view)
view.invalidate
end
def onLButtonDown(flags, x, y, view)
if @st == 0
input = Sketchup::InputPoint.new
input.pick view, x, y
face2 = input.face
if face2
@st += 1
mats = Sketchup.active_model.materials
mat = mats.add("green") unless mat = mats["green"] # or another name
mat.alpha = 0.2 # or other transparency
path = input.instance_path.to_a
@gr = path.grep(Sketchup::Group).first
@original_mat = @gr.material
@gr.material = mat if @gr
end
else
@st = 0
@gr.material = @original_mat #
end
end
end
end
Don’t be shy!
But: You should leave your bad habit of quoting unnecessarily long codes, again and again…
@majid866, I gave you an example of proper indentation of Ruby code. Please learn from it.
-
"Outdented " comment lines make code more difficult to read.
-
Each one of your extensions (plugins) should be within a submodule of your top level namespace module (as I showed in the linked example.)