Complex scripting/plugin - to create a component library
-
Sorry... you try.
I do have real [paid] work to do too...
It's not that hard to take the bits and get a single working tool...
It'll be good experience -
Done
I think?` ### PURGE UNUSED COMPONENTS
Sketchup.active_model.definitions.purge_unusedSETUP LIST OF NAMES
model=Sketchup.active_model
defs=model.definitions
cnames=[]
defs.each{|d|cnames << d.name}
cnames.sort!f='P:\02 General\Resource Library\People\JPEG'
cnames.each{|name|
d=defs[name]
bb=Gem::Boundingbox.new
d.entities.each{|e|bb.add(e.bounds)}ADD IMAGE TEXTURES
img=d.entities.add_image(File.join(f, File.basename(f, ".*")+".jpg"), [-1.mm,-1.mm,0], bb.width+2.mm, bb.height+2.mm)
img.explode
togos=[]
d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup::Edge) and e.faces.length<2}
d.entities.erase_entities(togos)
d.entities.each{|e|e.reverse! if e.is_a?(Sketchup::Face) && e.normal!=Z_AXIS}STAND COMPONENT CONTENTS TO VERTICAL
tr=Geom::Transformation.rotation(ORIGIN, X_AXIS, -90.degrees)
d.entities.transform_entities(tr, d.entities.to_a)
}FACE ME
cnames.each{|name|
defs[name].save_as(File.join(f, File.basename(f, ".*")+".skp"))
}REMOVE OUTER EDGE LEFT FROM EXPLODED IMAGE
img.explode
togos=[]
d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup::Edge) and e.faces.length<2}
d.entities.erase_entities(togos)REMOVE HOLES
faces=[]
d.entities.each{|e|faces << e if e.is_a?(Sketchup::Face)}
(faces.length-1).times{
for face in faces
if face.valid?
for edgeuse in face.outer_loop.edgeuses
if not edgeuse.partners[0] ### outermost face
faces = faces - [face]
loops = face.loops
for loop in loops
for fac in faces
if fac.valid? and (fac.outer_loop.edges - loop.edges) == []
faces = faces - [fac]
fac.erase! if fac.valid?
### fac abutts kept face so it must be erased...
end #if fac
end #for fac
end #for loop
end #if outermost
end #for edgeuse
end #if valid
end #for face
}#times` -
Needs testing - but looks reasonably convincing...
Indent the various parts of the code to make it 'readable'...
[Get Notepad++ - recommended for code editing etc]
Put your code inside a module thus:module LukeR def self.importer() ### add your code here end end
Usage: in the Ruby Console type
LukeR.importer
+ <enter>Change its name[s] as desired...
Later you can add your own new methods too like
LukeR.discombobulator
-
Last couple of points.
Using jpeg images as textures allows the faces to display received shadows [provided the containing object is set to do so too].
Using png images means they don't take shadows at all - the advantage is that they can have a transparent background so small 'holes' will be 'see-through' even if the face has no corresponding small hole.The other issue is hiding the edges of the faces within the component.
This easily done by adding a block of code near the end of each definition's processing...
d.entities.each{|e|e.hidden=true if e.is_a?(Sketchup::Edge)}
Only the component's faces are visible.
If View > Hidden Geometry is set ON the edges display as 'dotted' lines -
Managed to use a batch action in illustrator to successfully ungroup/explode all the components so that issue is solved.
Just tried saving the file as a .rb in the plugins folder and got and error. I am really not sure what I sould really do? Does the file name matter?
module LukeR def self.importer() ### PURGE UNUSED COMPONENTS Sketchup.active_model.definitions.purge_unused ### SETUP LIST OF NAMES model=Sketchup.active_model defs=model.definitions cnames=[] defs.each{|d|cnames << d.name} cnames.sort! f='P;\02 General\Resource Library\People\JPEG' cnames.each{|name| d=defs[name] bb=Gem;;Boundingbox.new d.entities.each{|e|bb.add(e.bounds)} ### ADD IMAGE TEXTURES img=d.entities.add_image(File.join(f, File.basename(f, ".*")+".jpg"), [-1.mm,-1.mm,0], bb.width+2.mm, bb.height+2.mm) img.explode togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) d.entities.each{|e|e.reverse! if e.is_a?(Sketchup;;Face) && e.normal!=Z_AXIS} ### STAND COMPONENT CONTENTS TO VERTICAL tr=Geom;;Transformation.rotation(ORIGIN, X_AXIS, -90.degrees) d.entities.transform_entities(tr, d.entities.to_a) } ### FACE ME cnames.each{|name| defs[name].save_as(File.join(f, File.basename(f, ".*")+".skp")) } ### REMOVE OUTER EDGE LEFT FROM EXPLODED IMAGE img.explode togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) ### REMOVE HOLES faces=[] d.entities.each{|e|faces << e if e.is_a?(Sketchup;;Face)} (faces.length-1).times{ for face in faces if face.valid? for edgeuse in face.outer_loop.edgeuses if not edgeuse.partners[0] ### outermost face faces = faces - [face] loops = face.loops for loop in loops for fac in faces if fac.valid? and (fac.outer_loop.edges - loop.edges) == [] faces = faces - [fac] fac.erase! if fac.valid? ### fac abutts kept face so it must be erased... end #if fac end #for fac end #for loop end #if outermost end #for edgeuse end #if valid end #for face }#times end end
ERROR
LukeR.importer Error; #<NameError; C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;17;in `importer'; uninitialized constant LukeR;;Gem> C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;17 C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;15;in `each' C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;15;in `importer' (eval);0
Nearly there now!
Thanks again TIG -
Typo
bb=Gem::Boundingbox.new
should be
bb=Geom::Boundingbox.new
The error messages show what's wrong 'Gem' and the line number - here '17'...
-
Ahh thank you. Will try again.
I looked there and thought it was the double "::" that was the issue -
I got the same error:
LukeR.importer Error; #<NoMethodError; undefined method `new' for ;Boundingbox;Symbol> C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;17 C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;15;in `each' C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;15;in `importer' (eval);17
module LukeR def self.importer() ### PURGE UNUSED COMPONENTS Sketchup.active_model.definitions.purge_unused ### SETUP LIST OF NAMES model=Sketchup.active_model defs=model.definitions cnames=[] defs.each{|d|cnames << d.name} cnames.sort! f='P;\02 General\Resource Library\People\JPEG' cnames.each{|name| d=defs[name] bb=Geom;;Boundingbox.new d.entities.each{|e|bb.add(e.bounds)} ### ADD IMAGE TEXTURES img=d.entities.add_image(File.join(f, File.basename(f, ".*")+".jpg"), [-1.mm,-1.mm,0], bb.width+2.mm, bb.height+2.mm) img.explode togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) d.entities.each{|e|e.reverse! if e.is_a?(Sketchup;;Face) && e.normal!=Z_AXIS} ### STAND COMPONENT CONTENTS TO VERTICAL tr=Geom;;Transformation.rotation(ORIGIN, X_AXIS, -90.degrees) d.entities.transform_entities(tr, d.entities.to_a) } ### FACE ME cnames.each{|name| defs[name].save_as(File.join(f, File.basename(f, ".*")+".skp")) } ### REMOVE OUTER EDGE LEFT FROM EXPLODED IMAGE img.explode togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) ### REMOVE HOLES faces=[] d.entities.each{|e|faces << e if e.is_a?(Sketchup;;Face)} (faces.length-1).times{ for face in faces if face.valid? for edgeuse in face.outer_loop.edgeuses if not edgeuse.partners[0] ### outermost face faces = faces - [face] loops = face.loops for loop in loops for fac in faces if fac.valid? and (fac.outer_loop.edges - loop.edges) == [] faces = faces - [fac] fac.erase! if fac.valid? ### fac abutts kept face so it must be erased... end #if fac end #for fac end #for loop end #if outermost end #for edgeuse end #if valid end #for face }#times end end
-
If you read it although it's the same line of code it is ANOTHER error!
Another daft typo!
It should actually beBounding**B**ox
NOT
Boundingbox
So the line should be
bb=Geom::BoundingBox.new
I didn't spot that either...
Incidentally the double :: is used to show the
Module::Class
A . shows the method [def] thus:
Module::Class.method()
You can also have aModule.method()
Sketchup and its related modules, like Geom, have both classes/methods and methods...The 'o' was simply missed out of the 'Geom' module's name, causing the error...
When testing a script the line references in errors are very useful [Notepad++ will display line numbers under one of it's Settings...]
A , instead of a . [or vice versa], a missing ( or } etc, a simple spelling error etc, can mess everything up big time... But if you know the line you can usually find the error easily... -
Ah ok Thankyou, I didn't realise it was case sensitive on commands! Will try again
-
Can't work this one out:
LukeR.importer C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;21; warning; Could not create Image for P;/02 General/Resource Library/People/JPEG/JPEG.jpg Error; #<NoMethodError; undefined method `explode' for nil;NilClass> C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;22 C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;15;in `each' C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;15;in `importer' (eval);0
module LukeR def self.importer() ### PURGE UNUSED COMPONENTS Sketchup.active_model.definitions.purge_unused ### SETUP LIST OF NAMES model=Sketchup.active_model defs=model.definitions cnames=[] defs.each{|d|cnames << d.name} cnames.sort! f='P;\02 General\Resource Library\People\JPEG' cnames.each{|name| d=defs[name] bb=Geom;;BoundingBox.new d.entities.each{|e|bb.add(e.bounds)} ### ADD IMAGE TEXTURES img=d.entities.add_image(File.join(f, File.basename(f, ".*")+".jpg"), [-1.mm,-1.mm,0], bb.width+2.mm, bb.height+2.mm) img.explode togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) d.entities.each{|e|e.reverse! if e.is_a?(Sketchup;;Face) && e.normal!=Z_AXIS} ### STAND COMPONENT CONTENTS TO VERTICAL tr=Geom;;Transformation.rotation(ORIGIN, X_AXIS, -90.degrees) d.entities.transform_entities(tr, d.entities.to_a) } ### FACE ME cnames.each{|name| defs[name].save_as(File.join(f, File.basename(f, ".*")+".skp")) } ### REMOVE OUTER EDGE LEFT FROM EXPLODED IMAGE img.explode togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) ### REMOVE HOLES faces=[] d.entities.each{|e|faces << e if e.is_a?(Sketchup;;Face)} (faces.length-1).times{ for face in faces if face.valid? for edgeuse in face.outer_loop.edgeuses if not edgeuse.partners[0] ### outermost face faces = faces - [face] loops = face.loops for loop in loops for fac in faces if fac.valid? and (fac.outer_loop.edges - loop.edges) == [] faces = faces - [fac] fac.erase! if fac.valid? ### fac abutts kept face so it must be erased... end #if fac end #for fac end #for loop end #if outermost end #for edgeuse end #if valid end #for face }#times end end
-
It's because it's another typo !
Line#21 should read
img=d.entities.add_image(File.join(f, File.basename(**name**, ".*")+".jpg"), [-1.mm,-1.mm,0], bb.width+2.mm, bb.height+2.mm)
sorry... -
Got some more issues TIG
Its getting there!-
It was rotating them the wrong angle so I change "-90" to "90" - so this is solved.
-
The result is just one component left - dont know where everything else went
-
For the one component that is left the face me doesnt seem to be working
-
I don't think it likes the img.explode on line 39
LukeR.importer Error; #<NameError; undefined local variable or method `img' for LukeR;Module> C;/Program Files/Google/Google SketchUp 8/Plugins/component_import.rb;39 (eval);0
module LukeR def self.importer() ### PURGE UNUSED COMPONENTS Sketchup.active_model.definitions.purge_unused ### SETUP LIST OF NAMES model=Sketchup.active_model defs=model.definitions cnames=[] defs.each{|d|cnames << d.name} cnames.sort! f='P;\02 General\Resource Library\People\JPEG' cnames.each{|name| d=defs[name] bb=Geom;;BoundingBox.new d.entities.each{|e|bb.add(e.bounds)} ### ADD IMAGE TEXTURES img=d.entities.add_image(File.join(f, File.basename(name, ".*")+".jpg"), [-1.mm,-1.mm,0], bb.width+2.mm, bb.height+2.mm) img.explode togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) d.entities.each{|e|e.reverse! if e.is_a?(Sketchup;;Face) && e.normal!=Z_AXIS} ### STAND COMPONENT CONTENTS TO VERTICAL tr=Geom;;Transformation.rotation(ORIGIN, X_AXIS, 90.degrees) d.entities.transform_entities(tr, d.entities.to_a) } ### FACE ME cnames.each{|name| defs[name].save_as(File.join(f, File.basename(f, ".*")+".skp")) } ### REMOVE OUTER EDGE LEFT FROM EXPLODED IMAGE img.explode togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) ### REMOVE HOLES faces=[] d.entities.each{|e|faces << e if e.is_a?(Sketchup;;Face)} (faces.length-1).times{ for face in faces if face.valid? for edgeuse in face.outer_loop.edgeuses if not edgeuse.partners[0] ### outermost face faces = faces - [face] loops = face.loops for loop in loops for fac in faces if fac.valid? and (fac.outer_loop.edges - loop.edges) == [] faces = faces - [fac] fac.erase! if fac.valid? ### fac abutts kept face so it must be erased... end #if fac end #for fac end #for loop end #if outermost end #for edgeuse end #if valid end #for face }#times end end
-
-
I would have thought -90.degrees was the correct angle... but if +90 works use it
I'm not sure how you are adding the initial components - importing as dxf/dwg outline ?
Before you add the images to their matching components made from the CAD files... do you have one of every type of component in the model ?? Remember this code is just to add an image to each preexisting component with the same name...You have a spurious
img.explode
line of code at line#39 remove it: it must have got copied down from where it's used earlier... and I'd not noticed it before...There's currently no code to make each component a 'faceme' type...
If you want that, then in the block {} that's processing the definition 'd' add a line
d.behavior.always_face_camera=true
-
@unknownuser said:
I'm not sure how you are adding the initial components - importing as dxf/dwg outline ?
Before you add the images to their matching components made from the CAD files... do you have one of every type of component in the model ?? Remember this code is just to add an image to each preexisting component with the same name...The .dwg files are imported into sketchup pro. But I used a batch import command I found elsewhere and it seems to work well. It will import every .dwg file in a selected folder, it imports all of these files into the current model - I used a new file so theres nothing else in it (apart from the default 2d woman!, but she got deleted). Each .dwg file is made into a component with the same name as the .dwg file. - so this should all match up with the file names of the jpegs in P:\02 General\Resource Library\People\JPEG
I have also attached an image that should help show what the sketchup model is like.
These components are all just outlines with no faces. just lines.example:
0001 vyonyx_couple_001.jpg
goes with
0001 vyonyx_couple_001.dwgHope this helps.
@unknownuser said:
You have a spurious
img.explode
line of code at line#39 remove it: it must have got copied down from where it's used earlier... and I'd not noticed it before...Ok will delete it.
@unknownuser said:
There's currently no code to make each component a 'faceme' type...
If you want that, then in the block {} that's processing the definition 'd' add a line
d.behavior.always_face_camera=true
Sorry I dont understand this
Shall I copyd.behavior.always_face_camera=true
into the script? where does it go?If it helps I have also found that it is creating a file in "P:\02 General\Resource Library\People\JPEG" called "JPEG.skp" - this is empty though.
If something is trying to save the components as .skp files, dont worry about this as long as they are in the same model I can just save all the components in the model via the components window.
Heres the current code:
module LukeR def self.importer() ### PURGE UNUSED COMPONENTS Sketchup.active_model.definitions.purge_unused ### SETUP LIST OF NAMES model=Sketchup.active_model defs=model.definitions cnames=[] defs.each{|d|cnames << d.name} cnames.sort! f='P;\02 General\Resource Library\People\JPEG' cnames.each{|name| d=defs[name] bb=Geom;;BoundingBox.new d.entities.each{|e|bb.add(e.bounds)} ### ADD IMAGE TEXTURES img=d.entities.add_image(File.join(f, File.basename(name, ".*")+".jpg"), [-1.mm,-1.mm,0], bb.width+2.mm, bb.height+2.mm) img.explode togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) d.entities.each{|e|e.reverse! if e.is_a?(Sketchup;;Face) && e.normal!=Z_AXIS} ### STAND COMPONENT CONTENTS TO VERTICAL tr=Geom;;Transformation.rotation(ORIGIN, X_AXIS, 90.degrees) d.entities.transform_entities(tr, d.entities.to_a) } ### FACE ME cnames.each{|name| defs[name].save_as(File.join(f, File.basename(f, ".*")+".skp")) } ### REMOVE OUTER EDGE LEFT FROM EXPLODED IMAGE togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) ### REMOVE HOLES faces=[] d.entities.each{|e|faces << e if e.is_a?(Sketchup;;Face)} (faces.length-1).times{ for face in faces if face.valid? for edgeuse in face.outer_loop.edgeuses if not edgeuse.partners[0] ### outermost face faces = faces - [face] loops = face.loops for loop in loops for fac in faces if fac.valid? and (fac.outer_loop.edges - loop.edges) == [] faces = faces - [fac] fac.erase! if fac.valid? ### fac abutts kept face so it must be erased... end #if fac end #for fac end #for loop end #if outermost end #for edgeuse end #if valid end #for face }#times end end
-
You have got some of your coding steps in a tangle...
I'll fix it and post a working [hopefully] version soonest...Incidentally, you don't need to open SketchUp with 'the 2d-woman' etc.
You can delete her, Model Info > Statistics > Purge Unused...
Then set other values exactly as desired - Units, number of dp's, no-snapping, no-unit-suffix, Text font/size, Dimension defaults etc.
Then under File > Save as Template. Under Preferences set that as your default template, thereafter every time you open a new SKP it will be empty and have the exact settings you prefer... -
Ok Thank you!!!!!!!!
~~I have used sketchup for 5 years and never bothered to change the default style!
Thanks ~~
CHANGED! -
Here it is:
I can't try it because I have no paired dwg/image sets...### Usage; Ruby Console type LukeR.importer require('sketchup.rb') module LukeR def self.importer() model=Sketchup.active_model defs=model.definitions ### PURGE UNUSED COMPONENTS [NOT NEEDED IF YOU DO IT MANUALLY FIRST] #defs.purge_unused ### SETUP LIST OF NAMES etc cnames=[] defs.each{|d|cnames << d.name if File.extname(d.name).downcase == '.dwg'} cnames.sort! fj='P;\02 General\Resource Library\People\JPEG' ### for images ff='P;\02 General\Resource Library\People' ### for saved SKPs cnames.each{|name| puts name ### SET UP defn etc d=defs[name] bb=Geom;;BoundingBox.new d.entities.each{|e|bb.add(e.bounds)} ### ADD IMAGE TEXTURES img=d.entities.add_image(File.join(fj, File.basename(name, ".*")+".jpg"), [-1.mm,-1.mm,0], bb.width+2.mm, bb.height+2.mm) img.explode ### REMOVE img's UNWANTED PERIMETER togos=[] d.entities.each{|e|togos << e if e.valid? and e.is_a?(Sketchup;;Edge) and e.faces.length<2} d.entities.erase_entities(togos) ### ENSURE FACES ARE 'UP' d.entities.each{|e|e.reverse! if e.is_a?(Sketchup;;Face) && e.normal!=Z_AXIS} ### STAND COMPONENT'S CONTENTS TO BE VERTICAL tr=Geom;;Transformation.rotation(ORIGIN, X_AXIS, 90.degrees) d.entities.transform_entities(tr, d.entities.to_a) ### MAKE IT A FACE-ME COMPONENT d.behavior.always_face_camera=true ### REMOVE ANY 'HOLES' faces=[] d.entities.each{|e|faces << e if e.is_a?(Sketchup;;Face)} (faces.length-1).times{ for face in faces if face.valid? for edgeuse in face.outer_loop.edgeuses if not edgeuse.partners[0] ### outermost face faces = faces - [face] loops = face.loops for loop in loops for fac in faces if fac.valid? and (fac.outer_loop.edges - loop.edges) == [] faces = faces - [fac] fac.erase! if fac.valid? ### fac abutts kept face so it must be erased... end #if fac end #for fac end #for loop end #if outermost end #for edgeuse end #if valid end #for face }#times ### FINALLY... SAVE IT INTO 'PEOPLE' AS A' SKP' d.save_as(File.join(ff, File.basename(name, ".*")+".skp")) }#names end#def end#module
-
SO MUCH BETTER!
Ok its getting there!
Its not working fully.
I have deleted parts of the script and tried it again at various stages.
I think the deleting the img edges after exploding isnt working. I think the newly created face needs to be intersected with the rest of the outline (found that the whole rectangle is one face and currently ignores the outline).Can we add an intersect just after ### ADD IMAGE TEXTURES?
-
The
img.explode
ought to auto-intersect the image's face and the rest of the edges [I assume that the component 'outline' consists of just edges ??]
However, as you suggest... the following code inserted immediately after the 'img.explode' line of code, should ensure proper intersection, if it's possible...
t=Geom::Transformation.new() d.entities.intersect_with(false, t, d.entities, t, true, d.entities.to_a)
Things that might stop this being always effective are:
that the outline edges are not quite coplanar and therefore don't split the newly added image face:
the outline contains edges that are tiny in length, and thereby the Sketchup intersect method fails as both ends are deemed to be coincident and therefore the edge is not recognized and therefore no full loop is made as needed to hold a face...
If that's the case we can try to 'heal' tiny edges... but let's first see how the current fix-up ideas work...
Advertisement