I have posted my rendition of the "no temporary group" calculate volume solution.
See: Calculate volume on manifold surface without group & explode
Bonus method for a volume display string in model units:
I have posted my rendition of the "no temporary group" calculate volume solution.
See: Calculate volume on manifold surface without group & explode
Bonus method for a volume display string in model units:
As I mentioned in a reply the bug report (it is ridiculous and should be closed.)
Some of the coordinates are in MILLIONTHS (or smaller) of inches !
One near the end has a -16th exponent:
points << Geom::Point3d.new( 4.194623966922387e-16, 0.20218771239100042, 65.51048909232898 );
That is about 42 femtoinches. In other words,
42 millionths of a nanoinch !
(42 millionths of a millionth of an inch.)
Does the OP (@torel) understand that SketchUp has an internal coordinate tolerance of only 1 one thousandth of an inch ?
Why would anyone want to be passing SketchUp coordinate floats with up to 19 decimal places ?
def_Panel = component_instance.definition def_Panel.clear!
There is no method named " clear!" for the Sketchup::ComponentDefinition class, nor inherited from any of it's ancestor classes. (You are confusing the Entities#clear! method, which only acts upon instance objects within a definition's [or the model's] entities collection.)
There was never a specific method to delete a certain definition, before the version 2018 API.
See Sketchup::DefinitionList#remove(), which will also remove all instances of the definition argument as well as the definition object.
In older versions the only workaround is to do a purge_unused upon the Sketchup::DefinitionList collection as a whole. This sometimes can result in the deletion of wanted components (perhaps used by other plugins, but not yet having instances in the model.)
If you must do the purge, try to save up the names and paths of all the other unused components, and reload them after you do the purge that results in removing your definition.
The danger with this workaround is that you will also be purging "internal components" which are sets of geometry the user has created but not yet saved out to a component SKP file.
@skastafari said:
I am looking for a method to exclude pages from my animation similar to how the "Include in animation" checkbox works from within Sketchup's scene editor.
...
I had found a thread from Dan Rathbun somewhere dating a couple years back discussing a need for this, but I can't seem to find what the outcome was. If anyone knows, please advise.
FYI,... Finally, ... the API has been updated for version 2018 and higher ...
... both a query method and a setter method have been added to the Sketchup::Page class.
Wanted to point you towards a tutorial that is posted on the "official" Trimble forums:
[Tutorial] Ten Fundamentals About LayOut for Architects
[Create LayOut File from Scenes] talk, bugs & feature requests
David, why are using this crazy indentation ?
Ruby uses 2 space indents, and all code at the same level must be at the same indent:
def delete_attribute
mod = Sketchup.active_model
mod.definitions.each do |d|
d.instances.each do |i|
d.delete_attribute 'dynamic_attributes', 'lola'
i.delete_attribute 'dynamic_attributes', 'lola'
end
end
end
This way the beginning of blocks line up with the indent lines in code editors.
@artmusicstudio said:
UPDATE;:
is it possible to let the system scramble my programm only for me for testing, first?
YES. Go to the EW signing portal, and you will find detailed instructions:
https://extensions.sketchup.com/en/developer_center/extension_signature
@turbodizayn said:
Hi! Does it work in SU2016 ? I have a message, " Could not activate SketchUp application window."
I just tested version 2 of "ruby_calc_2.rb" in SketchUp 2016, and this works.
Version 2 is in this post:
http://sketchucation.com/forums/viewtopic.php?f=180&t=22660&view=unread#p535117
What is "it" you refer to ?
You are attempting to write directly to the SketchUp registry hive whilst SketchUp itself is open ?
IF SO, Do you expect SketchUp to be able to handle this ?
Usually SketchUp overwrites any changes any code makes while SketchUp is open.
Generally, This is NOT a safe scenario.
@klpauba said:
That extension works with the free version of Sketchup but I think the Pro version (with its solid tools and Layout), and with the help of some custom code, is much better suited for timber framing design.
Yesterday SketchUp 2018 Pro was released, and with it we now have a Ruby API for creating and accessing LayOut documents from SketchUp. (A live in LayOut API with application hooks has not yet been implemented, but is likely within a version or two.)
Doc: LayOut API overview
Doc: Layout module
This is important for you to know that SketchUp Make is discontinued (and will not be updated beyond v2017.) It is replaced by the cloud SketchUp Free (formerly my.sketchup) which as yet has no API, and when it gets one it'll likely be Javascript rather than Ruby.
@klpauba said:
Let's say the design is pretty much finished and I wish to generate a shop drawing for the left post. I would select the post and choose the "Make Shop Drawing" item from the context menu. The script would copy the selected post, make it unique and trim the post with each intersecting component (the beam, right brace and two pegs).
This is correct.
(Not a timber person, but am a fan of "BarnBuilders". Wouldn't the peg holes be drilled in place after the bent is assembled on site? I could see starting a pilot hole in the post.)
@klpauba said:
It would then create a group (maybe in a layer named "Shop Drawing" perhaps) with four copies of the post (now with all of the mortises and peg holes). The four copies give the parallel projection view of each of the sides of the post that can be brought into a layout viewport for dimensioning.
...
I was thinking of modifying the script to create a "Post Shop Drawing" Scene showing just the "Shop Drawing" layer the group of four copies positioned in the window with all the right settings (if the script doesn't do that for me).
NO. This is not how it is done for LayOut. ONE copy is made and moved off to the side, and perhaps set to use it's own "detail" layer.
Then, four scenes (camera positions) are created for the 4 viewports in LayOut, each showing one of the post's sides (in each of the 4 scenes the "detail" layer is set "visible" whilst all others are "off" [except for "Layer0" the primitives layer which must always be visible].)
@klpauba said:
I have the ruby script doing these steps right now (short of creating the new layer) but the shop drawings are saved to a separate file.
You can have many pages in a LayOut document each with as many viewports that correspond to a scene page in the SketchUp model. It is not really necessary to have separate documents.
BUT, you may if you choose to. A single LayOut document may have scene viewports from multiple SKP models, or a multiple LayOut documents can have scenes from a single SKP model. (The latter seems to be the closest to what you are doing now.)
@klpauba said:
I would like to keep the original (unmodified) post in place so that if I later decide to, say, replace the 30-60-90 degree brace that's shown with a more conventional 45 degree brace, I can just replace the one that's there, select the post and execute the script once again (presuming I can replace the group in the "Post Shop Drawing" layer with the new one).
The original "unmods" could be associated with the "working" layer up until the point when you do the intersection, and make them unique. The code could create a "unmod" copy and put it on a hidden layer, but in proper position for possible mod later.
OR, the code could have a command to recreate (instantiate) an "unmod" post at a later date using the current transform of the "moded" post. (This way you don't have unused geometry bloating the model. The same would need to be done with the beams. I prefer this workflow.)
Another alternative is to build the frame and copy the entire thing perhaps as a unique assembly component, before adding the bracing ? This could be all on a hidden later "in limbo" so to say. So that any timber can be copied "in place" (already having the correct transform) to the main "working" layer.
There might be a plugin out there called "Selection Memory" or similar.
@klpauba said:
I got an error on the console implying
originalwas deleted.
It probably was. As I said, boolean operations create a new original instance that is always a Sketchup::Group object, which is an instance of a new cloned Sketchup::ComponentDefinition object (with it's #group? flag set true.)
This has bothered users and coders in the past who'd rather like the instances to remain as Sketchup::ComponentInstance objects. (Hence Jim's Trim and Keep plugin.)
@klpauba said:
The extension I'm writing allows me to select any one instance of the timber and it then trims the beams (with tenons), braces (also with tenons), pegs, roof rafters, etc. that intersect with it.
The problem is that in SketchUp instances do not have geometry collections, only definitions do. So every instance of a certain definition must be geometrically identical. When the user double-clicks to enter the editing context of an instance, they are actually then within it's definition's local geometry collection. So the user is actually editing every one of the definition's instances simultaneously.
To get around this, a user or coder can (like sometimes the Dynamic Component engine does,) make the instance unique, which clones the original picked instance's definition to a new unique definition. Then the user or coder can modify that definition's geometry without effecting any instance's of the original definition.
http://ruby.sketchup.com/Sketchup/ComponentInstance.html#make_unique-instance_method
@klpauba said:
I want to use the difference between the volume of the selected component and the volume of the resultant solid to determine the amount of wood that needs to be removed -- this would be used to arrive at a rough estimate of the effort required to cut the timber.
Certainly doable as both definition's would be in the model. You can save the original's volume as you've been doing in the "trimmed" definition, or save an attribute that points at the original definition object.
@klpauba said:
The resultant solid is then formatted as a shop drawing, saved to a separate .skp file, and then deleted from the model (thus, losing the any attributes that would have been saved with the instance).
Right, because saving a component saves it as a component definition SKP.
But usually coders do not separate out the components into separate files. It is easier to insert a new instance perhaps off to the side of the assembly, and have it assigned to a scene specific layer that is visible only on that scene, then this scene will correspond to a viewport in LayOut.
DaveR (who designs furniture) has explained this a myriad of times in the forums.
@klpauba said:
I think you meant "This statement will always be false ...", right (the comparison is !=)?
yes.
@klpauba said:
I had read the documentation of set_attribute and it mention that it returns "the newly set value if successful". It doesn't mention what it'll return if unsuccessful so I assumed 'nil' or a null string (in Python, they're different but I'll have to look it up for Ruby). My assumptions were incorrect so I'll change the code to your suggestion (besides, I like your code better) --- THANKS!
Since v2016 if the key is nil or empty, it will raise an exception:
Error: #<ArgumentError: Key cannot be empty>
Otherwise the method will convert any argument to a string if it can, and if it cannot for the value, then it'll just silently store "nil" in the dictionary.
So, basically do validation in your code. (Ie, test for nil values etc.)
Ruby core has a #nil? instance method for all objects that is preferable to:
obj == nil
ie:
obj.nil? or !obj.nil?
I notice some errors in your coding:
if original.volume != original.definition.set_attribute("timber", "volume_uncut", original.volume)
You cannot both test and set in the same statement like above. This statement will always be true because it sets the attribute every time.
Same for the second attribute volume test later.
You would need to first set the attribute when the instance is first created. Then test later something like:
original.definition.set_attribute("timber", "volume_uncut", original.volume) if original.volume != original.definition.get_attribute("timber", "volume_uncut")
Solid operations create a resultant Group. A Group is a special component that has a group flag set and does not appear in the Component Browser. But like any component has a definition.
So a group is really a "special" component instance.
Both instances and definition can be assigned attributes. Normally an instance type data attribute would be assigned to an instance's dictionary, not a definition's.
This is because instances can be scaled to change the volume. Sometimes the scaling is along a single axis resulting in a "stretch" of the original. (Different instances of the same definition can be scaled and stretched differently.)
Volume: Manifold solid instances of group and components have a built in API method to return the volume, named volume(), so there is no real need to waste time computing it and saving it to a dictionary attribute.
http://ruby.sketchup.com/Sketchup/Group.html#volume-instance_method
Now, Jim Foltz created a plugin called Trim and Keep that works around some of the annoying creating of new group from solid operations.
Look it up in the PluginStore.
When I update via EW (that indicates v3.0.2) I get v 3.0.1 after restarting SketchUp 2016.
(EDIT: okay, I see that v3.0.1 is the EW release. So, n/m.)
Manual d/l from GitHub:
https://github.com/Aerilius/sketchup-console-plus/releases/
Also, on my machine (Win7) with a high contrast custom charcoal system scheme the console is unusable.
Issue #17 filed at GitHub repo.
(Pic attached)

@tntdavid said:
Now, I only want to select the instances present in a selection of components.
Then use the grep method that TIG showed you to collect all instances in the selection set.
http://sketchucation.com/forums/viewtopic.php?f=180&t=68172&p=626519#p626479
Then build an array of definitions for those instances.
Then unique the array so that each definition reference appears only once in the array. (Or use a set.)
(And read the several examples in the SketchUp forum thread I pointed to above.)
@dan rathbun said:
There are some code examples here:
https://forums.sketchup.com/t/selecting-specific-entity-group-or-component-by-name/11469
@tntdavid said:
I want to delete hidden definitions and not instances.
Definitions are not hidden in the model, because they do not exist in the model entities collection (only instances do.)
When a definition is "hidden", it does not appear in the Components Browser list, but still is a member of the model's DefinitionList collection.
(2) You are wasting time pushing objects into the selection set.
This is not necessary in order to modify them.
(3) Instances do not "own" any nested components. Definitions own nested objects.
So you should be collecting a set of IKEA definitions, and then searching the definitions entities collection(s) (in that set,) for hidden objects.
When a definition has a child object that is hidden, it will be hidden in ALL of the definition's instances.
When you delete a hidden object from a definition, ALL of it's instances will have that child object deleted.