In following example code, I wish to select all faces that connected to face2 (box in this example) then read and change its opacity. Would you please help me for it…
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]
grp = mod.active_entities.add_group
face1 = grp.entities.add_face [pt1, pt2, pt3, pt4]
face1.pushpull -10
end
def deactivate(view)
view.invalidate
end
def onLButtonDown(flags, x, y, view)
mod = Sketchup.active_model
sel = mod.selection
# select face
input = Sketchup::InputPoint.new
input.pick view, x, y
view.model.active_path = input.instance_path.valid? ? input.instance_path : nil
face2 = input.face
# Code????
end
end
Assuming that your face2 is valid AND it’s a face - i.e. NOT a group as your title suggests ??
Try something like this…
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
}
PS: also include all of your code inside your own name-space module…
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.
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?
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 theview.draw_textinstance method,
as well as theColor classdescription 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 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