There might be a plugin out there called "Selection Memory" or similar.
Posts
-
RE: Activate last selection
-
RE: Some, but not all, definition attributes are set
@klpauba said:
I got an error on the console implying
original
was 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 clonedSketchup::ComponentDefinition
object (with it's#group?
flag settrue
.)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.
-
RE: Some, but not all, definition attributes are set
@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?
-
RE: Some, but not all, definition attributes are set
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")
-
RE: Some, but not all, definition attributes are set
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.
-
RE: [Plugin] Ruby Console+ (3.0.2) – updated 30.10.2017
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)
-
RE: Select instances in the selection
@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#p626479Then 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 -
RE: Remove and purge hidden components.
@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.
-
RE: Remove and purge hidden components.
(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 definitionsentities
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. -
RE: Remove and purge hidden components.
(1) Why are you putting quotes around IKEA ? (The regular expressions are themselves specially treated double quoted strings.)
-
RE: Select instances in the selection
There are some code examples here:
https://forums.sketchup.com/t/selecting-specific-entity-group-or-component-by-name/11469
These examples use the
==
but you can use regular expressions:
http://ruby-doc.org/core-2.0.0/Regexp.htmlbegins with:
=~ /\A#{name}/
Or the specific string "Handle" at start of string followed by: an optional whitespace character, underscore or dash; followed by a literal pound sign (which I escape just in case);
followed by an optional whitespace character; followed by one or more digit characters; just before the end of the string:
=~ /\AHandle(\s|-|_)?\#\s?\d+\z/
... and to make it non-case insensitive we can add a "i" switch at the end outside the slashes:
=~ /\AHandle(\s|-|_)?\#\s?\d+\z/i
If you are using Ruby 2.0 or higher you can also use the
String#start_with?()
method:
http://ruby-doc.org/core-2.0.0/String.html#method-i-start_with-3Finst.name.start_with?('Handle')
... or for case insensitive convert to a title:
inst.name.capitalize.start_with?('Handle')
-
RE: Dynamic Component Redraw
Scott Lininger left Trimble/SketchUp several years ago to start his own company. (He is unlikely to see or reply to your question. Ie, this topic thread is at least 7 years old!)
There are more recent threads on making custom DC functions (but you should not publish any custom changes.)
See this thread:
http://sketchucation.com/forums/viewtopic.php?f=180&t=67235 -
RE: Enable SketchUp tools
model = Sketchup.active_model tool = model.select_tool(nil)
https://ruby.sketchup.com/Sketchup/Model.html#select_tool-instance_method
@unknownuser said:
The select tool is activated if you pass
nil
to theselect_tool
method.
See this thread as well:
https://sketchucation.com/forums/viewtopic.php?t=34840
For SketchUp versions 2016+ they added new methods for window selection that can be used when writing your own Ruby tools:
https://ruby.sketchup.com/Sketchup/PickHelper.html#window_pick-instance_method
-
RE: Trying to set global axis from API
@ktkoh said:
So I am trying to align the Global Axes with a face to create a bounding box that matches the face plane. Then reset Global Axes to Default
It occurs to me that you really want the maximum 2d extents of the face, and really it might best be done virtually rather than modifying the geometry of the model.
Get the array of vertices in the face's outer loop.
Iterate that array mapping the vertex positions to a new 2D array.
(The first vertex should be put at coords 0,0. BTW, you can transform points if you have [or can get] the transformation of the original face. Ie, get the vector from the first vertex to the 2nd and use it to create a transformation for the face if you must.)
Lastly, get the max X and Y value for the 2D box's height and width. -
RE: Trying to set global axis from API
@ktkoh said:
xaxis = Geom;;Vector3d.new(3, 5, 0) > yaxis = xaxis * Z_AXIS > Sketchup.active_model.axes.set([10,0,0], xaxis, yaxis, Z_AXIS)
when I use this API example I get the error message:
undefined method ‘axes’ for #Sketchup::Model:0x9815c70The
Sketchup::Model#axes()
method and theSketchup::Axes
object class are only available with SketchUp version 2016 and higher.@ktkoh said:
So I am trying to align the Global Axes with a face to create a bounding box that matches the face plane. Then reset Global Axes to Default
You can never actually change the global axes. The global origin and axes are always where they are. (They are referenced via global constants
ORIGIN
,X_AXIS
,Y_AXIS
, andZ_AXIS
. **Do NOT attempt to reassign these constants!**You will only result in confusing other extensions and plugins.)The axes method and class changes the drawing axes, which is a temporary user axes that native tools honor, and plugins can honor IF they are written to specifically use the drawing axes. (Extension code will not use the custom drawing axes by default.)
-
RE: HTMLDialog vs WebDialog?
Basically I'm trying to prompt you to learn how to read Ruby error and backtrace messages.
“filename:lineNo: in
method”‘ or “filename:lineNo.”`http://ruby-doc.org/core-2.2.4/doc/syntax/exceptions_rdoc.html
http://ruby-doc.org/core-2.2.4/Exception.html@medeek said:
Okay 95% of that just went over my head, but I'll try and decipher into terms I can understand.
https://en.wikipedia.org/wiki/Data_validation
An example in Ruby of testing if an object reference is pointing at an object of a certain class:
if obj.is_a?(NilClass)
... or ...
if obj.is_a?(Float)
An example in Ruby of validating that an object reference call responds to a certain method call:
if obj.respond_to?(:methname)
... and testing for the "asterisk" method specifically:
if obj.respond_to?(:*)
@medeek said:
But why would this error only be raised for SketchUp running on MacOS and not Windows?
I don't know (offhand) as I avoid Macs myself. (But OSX and MS Windows use different sets of keycodes.)
Actually, looking at the backtraces (in your original error listing) the errors are kicked off by a LButtonDown keypress, but are occurring in the `` create_timber_geometry()`' method, lines 1064 and 1355.
-
RE: HTMLDialog vs WebDialog?
@medeek said:
The error codes posted above.
... are occurring (according to your error messages,) in "
medeek_roof_truss.rbs
", line 5726, in callback methodonLButtonDown
.In the first you are calling a
*()
method upon an object that is referencing the global singletonnil
object. Since theNilClass
does not have an "asterisk" method, aNoMethodError
is raised.The second method is caused by your code expecting a
Float
object, but getting aString
object instead.The answer is simple. Whenever an object reference could reference disparate types (classes) of obejcts, use a combination of type validation and Ruby
rescue
clauses with theonLButtonDown
callback method. -
RE: Excluding scenes from animation
@sdmitch said:
I found this (
view#camera=
) in the API but I have yet to get it to be recognized.See:
(SketchUp Developer forum): Setter #view.camera= Testing with Second Transition Time Argument@sdmitch said:
Perhaps it has been removed or never implemented.
The API docs are a bit confusing.
The
view#camera=
method is an overloaded method, which can be used two ways:-
with a single
Sketchup::Camera
object argument -
with a single
Array
argument of:[ Sketchup::Camera, Float ]
(The Float being the transition time.)
If you attempt to pass two arguments, of
Sketchup::Camera
andFloat
, the API ignores the second (time) argument and you get behavior #1. (Ie, a silent failure from what you'd expect.) -
-
RE: Excluding scenes from animation
@sdmitch said:
I'm still trying to solve the transition problem.
When you manually change scenes (and the model does not have specific transition and/or delay properties assigned to individual page objects,) then the model's global animation transition and delay settings are used.
Global settings are via:
Window > Model Info > AnimationGlobal transition and delay is accessible via the model's options provider objects.
model = Sketchup.active_model manager = model.options popts = Sketchup.active_model.options["PageOptions"] popts.each {|o| puts o } #=> ShowTransition #=> TransitionTime sopts = Sketchup.active_model.options["SlideshowOptions"] sopts.each {|o| puts o } #=> LoopSlideshow #=> SlideTime
A per scene page settings interface is not yet implemented, but I think I myself and others have requested it as a PRO feature request. (I believe it should be a Pro only feature myself.)
You can easily write a script to set per page transition and delay.
I also think some of the better animation extensions have UI interface to set per scene transition and delay. (I think Smustard's does.)