How to pushpull through a 3d object?
-
Another newbies ruby question...
I quite simply want to pushpull a 2d shape/face through a 3d object just as you would when normally modelling in sketchup to, say just cut a hole through a cube...
my code is for pushpull-ing a radius on a cubes corner
code atm is...
height=6.cm depth=2.cm length=100.cm edge_round=0.5.cm corner_round=2.5.cm model = Sketchup.active_model entities = model.active_entities objgroup=entities.add_group() usents=objgroup.entities face=usents.add_face([0,0,0],[length,0,0],[length,depth,0],[0,depth,0]) face.pushpull(-height) e1 = usents.add_edges [0,0,0],[0,0,height-corner_round] e2 = usents.add_arc [corner_round,0,height-corner_round], [-1,0,0], [0,1,0], corner_round, 0.degrees, 90.degrees e3 = usents.add_edges [corner_round,0,height],[length-corner_round,0,height] e4 = usents.add_arc [length-corner_round,0,height-corner_round], [-1,0,0], [0,1,0], corner_round, 90.degrees, 180.degrees e5 = usents.add_edges [length,0,0],[length,0,height-corner_round] e6 = usents.add_edges [0,0,height-corner_round],[0,0,height] e7 = usents.add_edges [0,0,height],[corner_round,0,height] e8 = usents.add_edges [length,0,height],[length-corner_round,0,height] e9 = usents.add_edges [length,0,height],[length,0,height-corner_round] cface1=usents.add_face(e2+e6+e7) cface1.pushpull(-depth)
the code is fine right up the the final pushpull line where it says...
Error: #<NoMethodError: undefined method
pushpull' for nil:NilClass> <main>:in
<main>'
SketchUp:1:in `eval'so i presume that this means it can't find the face i'm talking about?
can anyone see why this isn't working?
thanks again in advance
Matt -
You define edges e1 to e9, but then you only use three of those ?
cface1=usents.add_face(**e2+e6+e7**) cface1.pushpull(-depth)
If you add a 'p
' to the start of your code it prints its result in the Ruby Console.
So it'd be:
p cface1=usents.add_face(.....
If it prints a reference to a Face you are sorted, if it prints Nil it's failed.The issue is that you make the edges and get references to them [an arc returns an array of edges so that needs addressing too].
You need to add them to the add_face as either a list or an array, so it should be something like:
edges = [e2, e6, e7].flatten cface1=usents.add_face(**edges**)
The 'flatten
' explodes any arc's Array of edges, so then you end up with a single Array of the faces edges...Next issue is that the edges need to be coplanar AND in an order.
Check your arc parameters to ensure this...Assuming they are coplanar and would take a face if you wanted one you could consider making the edges in side a temporary group's entities, find faces for one edge, get a reference to the new face, then explode the group ? Then the drawn order is not important - e.g.
` group = usents.add_group()
gents = group.entitiesadd edges as you wish to 'gents'
e2 = gents.add_arc([corner_round,0,height-corner_round], [-1,0,0], [0,1,0], corner_round, 0.degrees, 90.degrees)
e6 = gents.add_edges([0,0,height-corner_round], [0,0,height])
e7 = gents.add_edges([0,0,height], [corner_round,0,height])
e7.find_faces
cface1 = gents.grep(Sketchup::Face)[0]
cface1.pushpull(-depth)
group.explode`etc
when all edges added to group
-
Thanks TIG
I only defined 9 edges because the plan was to use them later in the code - just managed to hit a stumbling block first!
the method including the flatten method seems to help but not solve the problem completely. I tried the grouping and then exploding method that you explained but didn't manage to get this to work. Also I didn't really understand why it might work?
After a bit of trial and error this is what I'm finding....
I can make a face that isn't connected to any other geometry from either points or edges - no problem.
However, if I want to draw a shape onto another existing face and then be able to reference the face bound by its edges (for example if I either wanted to pushpull it or use a followme method) then this only seems to work if I made the face using points rather than edges...?
So if I ask it to make a face onto an existing face using an array of edges and ask for the face class (puts face.class) i get NilClass. However, I had made the face using points instead and then ask for the class i get 'Sketchup::Face' - which means i now have a face to reference for pushpull etc...
This is fine for making things that are fairly simple and can practically be drawn using just points for reference, but it isn't practical where curves or radius's are involved and therefore you need to use edges in these situations...
I hope that this makes sense or am I missing something?
If I could turn an array of edges into an array of points then in theory that would work, but I don't know how to do that?
Any ideas??
Thanks again
Matt -
Make the new geometry inside a temporary group.
Make edges, find_faces of one edge you know will be the loop.
Get a reference to the face as I shewed...
PushPull in the group.
Explode the group when done.
If you have a series of ordered points [or edges] they will work with add_face
If you have a 'donut shape' face, you need to make the inner face [that will eventually be a hole], get a reference to it, then make the outer face, now erase the inner face to leave a hole.
Or find_faces for inner and outer loops' edges, then collect the faces into an arrayfaces=gents.grep(Sketchup;;Face) faces.each{|face| face.erase! if face.loops.length == 1 ## the face with will be the hole - erase it. face.loops.length > 1 ## will be the donut. }
Advertisement