How do I represent and keep a track of cuboids I create?
-
I have a written a simple tool that creates cuboids. All I do internally to create the cuboid is
model=Sketchup.active_model() ents = model.entities() group = ents.add_group() corners = get_corners() # Assume I've written a method that will return 4 corners of the face face = group.entities().add_face(corners[0], corners[1], corners[2], corners[3]) face.pushpull(pushpull_distance.mm) model.selection.add(@group) compInstance = @group.to_component
What I would like do?
I'd like to prevent the tool from creating any overlapping (or intersecting) cuboids. (see the attached image)My approach
- Represent the cuboid in the tool as a object
- Have an instance variable bb, which I'd set it with the boundbox of the cuboid
- Maintain a list of cuboid objects. Add this newly cuboid object to the list only if its bounding box doesn't contains? any of bbs in the list
- Now go ahead and actually draw
Questions
- Is my approach ok? Any easier way to achieve it.
- How to represent the cuboid? The piece of code face.pushpull(pushpull_distance.mm) creates the cuboid from the face, but it doesn't return any object that I could use
-
Have a look at the code for the Voxelize plugin.
The instances collection of your cuboid component's
ComponentDefinition
keeps track of the object inserted into the model. -
edit:
found out:
edges are numbered first
then the faces (depending on the order of the edges...
so it is rather easy to point out, which numbers are for the faces and delete thems selectivlely.
stanhello,
maybe i may expand this topic a bit:i just look for a way, how to identify the single faces on a cuboid (let's say, it is a cube, so it has 6 faces).
i would like to delete two of the four vertical faces,
so i cannot identify them by the normal vector only (just excluding the vertical ones).since the element are turned in different angles, also x- or y- direction is also not the exclusive factor.
so:
is there a way to find out the number of face (face 0 .. 5) somehow, to be sure, that these faces have always this number 'in the row' and then i could delete them by
face[x].erase! in EVERY 6-FACE-CUBOID
or something like that.
thanx stan
-
Dan, Thanks for the pointer. The plugin did help me understand the Sketchup environment more and solve my problem.
I wanted to keep a track of all the components that my tool was creating. Now I was not aware that the model.entities was already keeping track of them. So I traversed through the entities, checked if its a ComponentInstance, if it is, then check if its a component that my tool created, to get hold of it.
-
@bobdiya said:
I wanted to keep a track of all the components that my tool was creating. Now I was not aware that the model.entities was already keeping track of them. So I traversed through the entities, checked if its a ComponentInstance, if it is, then check if its a component that my tool created, to get hold of it.
That is the hard and slow way to do it.
Your components have a definition, an instance of
Sketchup::ComponentDefinition
.Get a list of all definitions from the model and search it for your definition.
cubedef = nil my_cuboids = [] model = Sketchup.active_model deflist = model.definitions found = deflist.find {|d| not d.image? && not d.group? && d.name == "cuboidski" } if found cubedef = found if cubedef.instances.size > 0 # your tool has cuboid instances in the model my_cuboids = cubedef.instances.dup # Select all cuboids; sel = model.selection if not sel.empty? old = sel.to_a sel.clear! end sel.add my_cuboids else # your tool has not been used yet. end else puts("cuboidski not found!") end
-
Dan,
Thanks for the code example. Representing and maintaining cuboids taken care of. I see why my code is slow. My approach scanned through all the entities, but you directly get the list of definitions and then you get the definition you are interested in. From there, its instances. Perfect!
One problem that I'm facing still how to figure out if two cuboids are intersecting.
- Is there a way(method) I can use to check if two components are intersecting?
I used the intersect method to see if it returned an empty BoundingBox, when I was comparing the BoundingBoxes of two cuboid instances that I wanted to check for intersection. But those BoundingBoxes were not the cuboid themselves, but I guess bounding boxes which are enclosure sort of thing to the component. So should I create these BoundingBox objects manually for each of cuboids so that I can use this method?
How do I approach this? -
@bobdiya said:
Is there a way(method) I can use to check if two components are intersecting?
On Pro edition you can use the boolean
intersect()
method, which should work even when the cuboid is rotated away from the global axis.@bobdiya said:
I used the intersect method to see if it returned an empty BoundingBox, when I was comparing the BoundingBoxes of two cuboid instances that I wanted to check for intersection. But those BoundingBoxes were not the cuboid themselves, but I guess bounding boxes which are enclosure sort of thing to the component. So should I create these BoundingBox objects manually for each of cuboids so that I can use this method?
How do I approach this?You do not need to create them and keep references to them. Think of it as that they always have bounds if they have dimension. Then access their bounding box instances only when comparing:
cube1.bounds.intersect(cube2.bounds).valid?
The drawback is that bounding boxes are always aligned with the global axis, even if the object has been rotated. So the bounding box may be larger than the cuboid if it was rotated less than 90 degrees off the global axis.
-
@dan rathbun said:
On Pro edition you can use the boolean
intersect()
method, which should work even when the cuboid is rotated away from the global axis.I dint know this. Thank you.
@dan rathbun said:
You do not need to create them and keep references to them. Think of it as that they always have bounds if they have dimension. Then access their bounding box instances only when comparing:
cube1.bounds.intersect(cube2.bounds).valid?
The drawback is that bounding boxes are always aligned with the global axis, even if the object has been rotated. So the bounding box may be larger than the cuboid if it was rotated less than 90 degrees off the global axis.
I get that I can use
cube1.bounds.intersect(cube2.bounds).valid?
when my (cubes)objects have dimensions. But given that the user is likely to rotate the cube (<90 degree off the global axis) then I will have to create and keep references to the bounding boxes? Because now the default bounding boxes are larger and they don't represent the bounds of the cube themselves. Correct? -
@bobdiya said:
But given that the user is likely to rotate the cube (<90 degree off the global axis) ... Because now the default bounding boxes are larger and they don't represent the bounds of the cube themselves. Correct?
True.
@bobdiya said:
... then I will have to create and keep references to the bounding boxes?
BUT then THOSE bounding boxes are not rotated,... their corners do not occupy the same vertices points that the cuboids do.
Meaning that cubiods could have been rotate away from each other... so as not to be intersecting after rotation.
Advertisement