Detecting duplicate components
-
I'd like to be able to detect when two components (don't care at all about groups or 'lesser' entities, though I doubt it makes much difference) are duplicates.
The obvious trivial test is to compare the component.definition.name but this takes no account of any axis flipping or scaling that has been applied. I'm not sure if there are any other attributes that should be considered yet. I suppose in some sense the applied materials might be important?
It's well over a quarter of a century since I last played with 4x4 geometric transforms (I wrote a really trivial solid modeller for a NatSemi 32000 based system I designed and built myself for a masters degree) and I'd rather not have to attempt to dig out that portion of my memory again; it's probably backed up on mouldy paper tape somewhere. I've been able to find some transform related extensions that TIG wrote up several years ago but I'm wondering if anyone has added code that could quickly compare two transforms and establish if they have nothing more than translation and rotation differences? I have a feeling that there might just be some neat trick to it. Like maybe applying the inverse of one transform to the other, cross-producting with the dot-product of jam and bread, adding the number we first thought of and then holding your finger in the wind to see if bananas are flying.
-
Dan, I don't think I made it clear what I need to find out - or possibly I don't understand what SU is doing underneath.
It's not that I need to find out if two references to components are to the actual same component, but that I need to weed out instances of the same component definition. The complication so far as I can discern is that two components where the definition is the same can have transformations that flip them (like pairs of table legs where each is a mirror of the other) or scale them. They may be the 'same component' so far as SUs need for storage is concerned but not from the point of view of wanting to build a list of components needing a parts drawing in my LO doc. Scaled items need separate drawings for the different dimensions, for example.
To use the table legs example again, there will likely be one definition that is used four times with two of them flipped. There might be a single screw definition used a couple of dozen times, with some scaled to play the part of 1" #8's and some scaled to be 2" #10s and a few ¾" #6's.
-
if inst_one.definition.object_id == inst_two.definition.object_id
Then these two instances are duplicates.But it's really quicker to go through the defintion list and access a definition
's instances collection:a test
active_model.definitions["Definition Name"].instances.include?(inst_in_question)
or select them all:
active_model.selection.add(active_model.definitions["Definition Name"].instances)
-
Ok.. gotcha.
So, start with getting all 4 table leg instances, thus:
legs = active_model.definitions["Table Leg"].instances
Now a
transformation
is a property of theComponentInstance
(assume thatlegs
has 4, in this case.)You can iterate your legs array and compare the transformation objects of the instances.
if legs[0].transformation == legs[1].transformation # do something elsif legs[0].transformation == legs[1].transformation.inverse # do something else end
To get more detailed, you'd need to get the matrix array of the transformations using their
to_a()
method.
See this topic:
The Transformation Matrix
.. otherwise do a forum search on keywords liking "scaling" "transformation" (or both) etc.
(This is one of the most discussed topics around here, it seems.)Also if you have the DynamicComponents extension loaded, it adds some scaling methods to Group and ComponentInstance.
Undocumented Geom::Transformation methods? -
@dan rathbun said:
See this topic:
The Transformation MatrixI'd spotted that particular one and to my amazement found that I even remembered most of the matrix stuff mentioned. After a quarter century that is a surprise!
@dan rathbun said:
otherwise do a forum search on keywords liking "scaling" "transformation" (or both) etc.
(This is one of the most discussed topics around here, it seems.)Also if you have the DynamicComponents extension loaded, it adds some scaling methods to Group and ComponentInstance.
Undocumented Geom::Transformation methods?Hadn't seen that topic though; that's interesting but a bit worrying. If it is only added by an extension, I imagine I'd have to check that it exists and is active on the target system.
Still searching around for a way to actually derive from a transform whether the component is flipped or scaled… this is fun, For a certain odd definition of the word 'fun'.
-
Damn. Thought I'd spotted a nice simple solution - ComponentInstance.equals? - which claims to compare the geometry. Sadly, that comparison seems not to care about flipping nor scaling. Poo.
-
@tim said:
@dan rathbun said:
Also if you have the DynamicComponents extension loaded, it adds some scaling methods to Group and ComponentInstance.
Undocumented Geom::Transformation methods?... If it is only added by an extension, I imagine I'd have to check that it exists and is active on the target system.
if the DC extension is loaded, Then:
` defined?($dc_observers)
>> global-variabledefined?(DCObservers)
>> constant`The keyword
defined?
returnsnil
(so evalsfalse
,) if the arg is undefined.And further if the DC extension is loaded:
Geom::Transformation.method_defined?(:rotx) %(#008000)[>> true] %(#000000)[As well as:] roty rotz xscale yscale zscale
Sketchup::ComponentInstance.method_defined?(:scaled_size) %(#008000)[>> true] %(#000000)[As well as:] local_transformation last_scaling_factors unscaled_size %(#000000)[(and one that only the DC extension should call:] set_last_size %(#000000)[)]
.
Advertisement