How to use Ruby API
-
This makes a 'list' called faces of all of the faces inside the group...
faces=[] ### *** note how the list must be defined outside of the {...} block group.entities.each{|e|faces<<e if e.class==Sketchup;;Face}This approach can be adjusted to suit any type of 'entities' list and any type of 'class' of thing you want to extract from it - faces, edges, cpoints, clines, text...
Then of course you can loop through you faces for say a particular material (or any other property)...red_faces=[] ### *** faces.each{|f|red_faces<<f if f.material.name=="Red"}red_faces now contains all of the group's faces that are "Red" etc etc...
PS: Note that the
.entitiesmethod returns all of the entities associated with the specified object - i.e. model/group/definition... There is another list of entities:model.active_entitiesthat applies to the current set of entities available in the present edit session - this could equivalent ot themodel.entitiesor if you are editing a group or component-definition the available entities within that - e.g.group.entities... -
OK, I put:
if e.is_a? Sketchup;;ComponentInstance name=e.definition.name#e.typename faces=e.definition.entities WMY_putdxf.get_faces(name,faces) endAnd:
def WMY_putdxf.get_faces(name,faces)# procedure or method faces.each do |e| info = e.typename if e.is_a? Sketchup;;Face UI.messagebox(name+"; "+info) end #endif end #end do end #end methodSo, you declare a array=[], but a collection (something like an array) makes itself?
OK, how do I make a collection of the geometric imformation inside each face so that I can access it later? Wild guess to start below:def WMY_putdxf.get_faces(name,faces)# procedure or method faces.each do |e| #why do we use e; can I use f? info = e.typename if e.is_a? Sketchup;;Face facegeo=e.something #get face geo collection goes here? end #endif end #end do end #end method -
@honoluludesktop said:
OK, I put:
I USE CAPITALS FOR EASE OF READING ONLY !!!
> if e.is_a? Sketchup;;ComponentInstance > name=e.definition.name#e.typename### NAME IS THE 'NAME' - LIKE 'BED' TYPENAME IS THE CLASS/KIND_OF ETC > faces=e.definition.entities### THERE WILL BE MORE THAN FACES IN ENTITIES - AT LEAST EDGES TO FORM THE FACES > WMY_putdxf.get_faces(name,faces)### IF YOU WANT TO PASS THE DEFINITION THEN PASS E.DEFINITION NOT ITS 'NAME' > ### REMEMBER THAT 'FACES' IS 'ENTITIES' THAT WILL INCLUDE FACES BUT NOT JUST FACES ALONE... > end >And:
> ### START DEF WITH lowercase LETTERS !!! wmy_putdxf etc > ### THIS GETS YOU NOTHING EXCEPT A MESSAGE LISTING THE DEF'S NAME AND EACH FACE IN TURN... > def WMY_putdxf.get_faces(name,faces)# procedure or method > faces.each do |e| > info = e.typename > if e.is_a? Sketchup;;Face > UI.messagebox(name+"; "+info) > end #endif > end #end do > end #end method >So, you declare a array=[], but a collection (something like an array) makes itself?
AN ARRAY FACES=[] IS A LIST
OK, how do I make a collection of the geometric imformation inside each face so that I can access it later? Wild guess to start below:### REMEMBER THE lowercase LETTERS TA THE START > def WMY_putdxf.get_faces(name,faces)# procedure or method > faces.each do |e| #why do we use e; can I use f? ### CAN USE ANY VARIBALE 'E' IS OFTEN USED FOR 'EntitY' > info = e.typename > if e.is_a? Sketchup;;Face > > facegeo=e.something #get face geo collection goes here? > > end #endif > end #end do > end #end method >HERE IS MY GET FACE VERSION...
if object.class==Sketchup;;ComponentInstance faces=[] object.definition.entities.each{|entity| faces<< entity if entity.class==Sketchup;;Face } ### now do stuff to these faces... end#ifDone with sub-defs or anything... Tests if the object is an Instance and if so make an Array [list] of its Definition's Entities' Faces to process...
-
Thanks guys. Will work on this later tonight after I get home. About the lowercase, if the def is inside a module, will it make a difference?
This runs ok on my system:
require 'sketchup.rb' module WMY_putdxf def WMY_putdxf.main model = Sketchup.active_model # make db of active model entities = model.active_entities selection = model.selection # make db of selections if model.selection.empty? entities = model.active_entities else entities = model.selection end # test if selection made entities.each do |e| # do loop through database and place entities in type array if e.is_a? Sketchup;;ComponentInstance #comp_file_name=e.definition.name name=e.definition.name#e.typename faces=e.definition.entities WMY_putdxf.get_faces(name,faces) end end end # .main method def WMY_putdxf.get_faces(name,faces)# procedure or method faces.each do |e| info = e.typename if e.is_a? Sketchup;;Face UI.messagebox(name+"; "+info) end #ednif end #end do end end # WMY_putdxf module #----------------menu------------------ if !file_loaded?(__FILE__) #_FILE_ permits renaming the file UI.menu("Plugins").add_item("Yet Another Test") { WMY_putdxf.main } end file_loaded(__FILE__)But with WMY_ as wmy_ this error message:
Error Loading File yet_another_script.rb
C:/PROGRA~1/Google/GO2494~1/Plugins/yet_another_script.rb:3: class/module name must be CONSTANTSorry for the uneven indenting, when I copy from notepad++ and paste, the indent spacing changes.
-
module names always must start with a capital letter. methods do not start with a cap. Classes start with a cap. That is the basic rule. Constants are variables that start with a capital letter, and should remain constant - like Pi.
Chris
-
@chris fullmer said:
module names always must start with a capital letter. methods do not start with a cap. Classes start with a cap. That is the basic rule. Constants are variables that start with a capital letter, and should remain constant - like Pi.
Chris
Normal convention is to type constants in all caps.
-
Sorry for the confusion
- I didn't realise there was an enclosing module / class. They need initial CAPITAL letter; whereas defs and variables need lowercase. Consonants ion caps e.g. ORIGIN... -
OK I am stuck again. Problem is with the last box of code below:
This is the main proc, methods below are at the bottom of the code in this section:
model = Sketchup.active_model entities = model.active_entities selection = model.selection if model.selection.empty? entities = model.active_entities else entities = model.selection end entities.each do |e| if e.is_a? Sketchup;;ComponentInstance the_name=e.definition.name stuff=e.definition.entities counter=0 faces=[] stuff.each do |e| if e.is_a? Sketchup;;Face counter=counter+1 faces.push e end ###if end ###loop points=[] add_face_vert_to_file(faces,points) make_comp_face_file(the_name,faces,counter,model,points) end ###if end ###loopMethod to make a collection of face.vertices
###make vertices file of faces in component def add_face_vert_to_file(faces,points) faces.each do |e| points.push e.vertices end ###end loop endMethod to make empty text file, then (where I fail) to take the face.vertices and copy them as string to the text file.
###create file ComponentName.txt def make_comp_face_file(the_name,faces,counter,model,points) the_line=the_name+" ",counter," faces" UI.messagebox(the_line) model_filename = File.basename(model.path) path=File.dirname(model.path)+"\\" out_name=the_name+".txt" out_path=path+out_name $mesh_file=File.new(out_path,"w") #HERE is problem code. How do I take the collection #of face.vertices and copy as strings to the text file. points.each do |e| $mesh_file.puts(e.x.to_s) $mesh_file.puts(e.y.to_s) $mesh_file.puts(e.z.to_s) end ###loop endAm writing with the Web Console, and having some problems. Saving seems to drop characters, and the indents are gone. Any ideas?
-
points.each do |e| $mesh_file.puts(e.x.to_s) $mesh_file.puts(e.y.to_s) $mesh_file.puts(e.z.to_s) end ###loopAdds x/y/z into file on separate lines...
to test if it's at least getting the points values use plain puts so it appears in the consolepoints.each do |e| puts(e.x.to_s) puts(e.y.to_s) puts(e.z.to_s) end ###loopTo write an xyz line use
points.each do |e| $mesh_file.puts(e.x.to_s+","+e.y.to_s+","+e.z.to_s) end ###loopDoes
$mesh_file=File.new(out_path,"w")actually make the file ?
You need to open the file for writing AND then close it after you are done writing to it.$mesh_file.closeperhaps it's still open and so a second [separate] attempt to write to it fails...
-
@thomthom said:
Normal convention is to type constants in all caps.
Oh yeah! I rarely intialize them. Thanks Thom,
Chris
-
TIG, Just got up, and finished reading at your post. Thanks I think I understand, and have a lot to work with.
$mesh_file=File.new(out_path,"w")
Made a 0 byte file that I can see in "My Computer". I assumed it was open, guess it wasn't:-). Looks like a lot of stuff to work on later today. Good advice about using "puts" to check output. I use the messagebox a lot but that is slow.
puts(e.x.to_s) prints Sketchup::Vertex:0xea24668 ?-(, Crossed this bridge once before, but don't recall how to get output as a number.
-
puts(e.x.to_s) should return a numerical "x" position if e is a Point3d object. if e is a vertex, it should return an error. If e is a vertex, you can do e.position.x and that will return the x position of the vertex.
That sounded confusing to me. A few more lines of your code and I could give a slightly more complete example.
Great job so far!
Chris
-
"oops: - I"
A little slow this morning, didn't get it until now. Thanks guys, lets see how far I can get with what I have before I, OOPS:-(, need help getting off the floor. Might not take too long.Tig, I can now open, write to, and close files:-)
Chris above here is where I stumbled on the code.
It occurred to me that a "method", a "function" in other languages (I missed this one), was in my day know as a "procedure", having evolved from a "[C}all". Before this I did a Basic "sub routine", itself born out of "jump xxxx:xxxx, where xxxx:xxxx began a set of instruction that ended in "return". Before "Buddha" it was all 1111's and 0000's

-
Help! How do I get a number that repersents the location of a face vertices? The following is setup for Web Console. When I output to UI.messagebox(e.vertices), I get:
#Sketchup::Vertex:0xfc83800#Sketchup::Vertex:0xfc837e8#Sketchup::Vertex:0xfc837d0
The main proc is at the bottom, and the methods are above it.
model = Sketchup.active_model entities = model.active_entities selection = model.selection ### Test is selection made if model.selection.empty? entities = model.active_entities else entities = model.selection end ###create file ComponentName.txt def make_comp_face_file(the_name,faces,counter,model) the_line=the_name+" ",counter," faces" UI.messagebox(the_line) model_filename = File.basename(model.path) path=File.dirname(model.path)+"\\" out_name=the_name+".txt" out_path=path+out_name end ###make vertices collection of faces in component def add_face_vertices_collect(faces,points) faces.each do |e| points.push e.outer_loop end ### loop end ###make 3dpoint from vertex HELP HERE!!!! I think def print_vertices_collect(points) points.each do |e| UI.messagebox(e.vertices) ###puts to test will be ###$points_file.puts(e.vertices)###put here when works end end ###Get su;;component collection entities.each do |e| if e.is_a? Sketchup;;ComponentInstance the_name=e.definition.name stuff=e.definition.entities faces=[] counter=0 ###Locate faces in each component and make faces collection stuff.each do |e| if e.is_a? Sketchup;;Face counter=counter+1 faces.push e end ###if end ###loop make_comp_face_file(the_name,faces,counter,model)####Have to points=[] add_face_vertices_collect(faces,points) ####nest these print_vertices_collect(points) ####later $points_file.close end ###if end ###loop -
The Vertex entity has a position.
point = vertex.positionThe position will be relative to parent container, and not relative the SketchUp axes.
-
### points>>>vertices vertices.each do |vertex| $points_file.puts(vertex.vertices.point.to_a) ### FILE of VERTICES POINTS AS AN ARRAY ONE PER LINE... end -
Hi guys, Thanks for your help. I stumbled on e.vertices.x.position after starting over. Now how do I read the SU Ruby API to make this easier to understand?-(
model = Sketchup.active_model entities = model.entities selection = model.selection if model.selection.empty? entities = model.active_entities else entities = model.selection end entities.each do |e| if e.is_a? Sketchup;;ComponentInstance ci_name=e.definition.name #UI.messagebox(ci_name) ci_collection=e.definition.entities #UI.messagebox(ci_collection) ci_collection.each do |e| ci_faces_collection=[] if e.is_a? Sketchup;;Face ci_faces_collection.push e ci_faces_collection.each do |e| faces_vertices_collection=[] if e.vertices faces_vertices_collection.push e puts(e.vertices.x.position) end end end end end end -
Edges, Loops, Curves, Faces, etc have
verticesand thoseverticeshave a positionvertices.position(i.e. a point)
points have x/y/z valuesvertices.position.x
DON'T muddle them up!
-
OK, so how do I get the coordinate values for each vertex on each face.vertices? I think I understand vertex.position, and face.vertices, but how do I get a collection of vertex for each vertices.
Can't be impossible, can it?
-
look at the Face.vertices here:
http://code.google.com/apis/sketchup/docs/ourdoc/face.html#vertices
it says what it returns - an array of vertx objects. So to get positions for all those vertices, you need to loop through that array. Something like this:
` vert_array = my_face.vertices
position_array = []
x_position_array = []vert_array.each do |v|
position_array << v.position
x_position_array << v.position.x
end`
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better π
Register LoginAdvertisement