Erase! gives an error: can't find parent
-
Clark,
Does the error line correspond to the erase! command? Or is it pointing to a different portion of your code?
-
Clark,
Yes, as you erase edges that bound faces, the face is removed from the selection automatically (since it no longer exists), and the objects' indices are shifted accordingly.
Given sel=model.selection followed by sel.each{|e| e.erase!}:
The script erases sel[0], an edge. That edge bounded a face at sel[1]. This shifts the object at sel[2] to sel[0], which is then ignored because the .each loop has already finished working on sel[0] and moved on to sel[1].
Furthermore, faces aren't the only culprits. Erasing anything could cause the next entity to be shifted to its index location, thus you can miss about 1/2 of the entities on any given pass of selection.each.
Better to add the selection entities to an array and cycle through the array rather than rely on selection.each
-
Thanks for jumping in Rick.
That is a great suggestion about adding them to an array and cycling through the array indexes.
-
Thanks Guys.
Yes, I can see now why it's happening, and also why it happens on this model and not others. Most of my models are components only.
But if I add the entities to my own array, and then erase them all, won't I run into a similar problem? If I erase an edge before I get to the face, I'll still try to erase the face, but it will be gone from the model.
The reason I'm using the selection is that it's easy to add all the entities to it. There's a sel.add that doesn't care what kind of thing I'm adding. If I make my own entities array, I have to know what each thing is and call the right add, as there's no generic add. CB.
-
also check with entity.valid? before doing stuff on an entity like this:
all_ent = [] Sketchup.active_model.entities.each do |ent| all_ent.push ent end all_ent.each {|ent| x.erase! if ent.valid?}
-
That's the stuff! Thanks, guys. All better now. CB.
-
Sketchup.active_model.entities.to_a.each{|e|e.erase! if e.valid?}
is a bit shorter and does the same...
-
Clark,
@unknownuser said:
The reason I'm using the selection is that it's easy to add all the entities to it. There's a sel.add that doesn't care what kind of thing I'm adding.
True, but .erase! does care what you're erasing (as you discovered), so you're still in the same boat with type checking. In fact, that's really the bottom line: check everything and assume nothing.
It's a hassle, but it's necessary, because inevitably someone will come along and provide unexpected input, and things will error out.
Regards, and happy coding!
-
TIG: to_a == Make into array? Undocumented or standard ruby?
Rick: I can add any kind of item to a generic array. I was stuck on using the entities container for some reason. Your cautionary point is well made.Thanks, guys. CB.
-
Standard ruby conversion methods include (but are not limited to):
.to_a - convert to an array
.to_i - convert to an integer
.to_f - convert to a float
.to_s - convert to stringThough standard ruby, they may not be applicable to all data types. SU adds more .to_n methods:
.to_feet - convert a number of inches to feet
.to_yard - convert a number of inches to yards
.to_mile - convert a number of inches to miles
.to_m - convert a number of inches to meters
.to_cm - convert a number of inches to centimeters
.to_mm - convert a number of inches to millimeters
.to_km - convert a number of inches to kilometers.feet - convert a number of feet to inches
.yard - convert a number of yards to inches
.mile - convert a number of miles to inches
.m - convert a number of meters to inches
.cm - convert a number of cm to inches
.mm - convert a number of mm to inches
.km - convert a number of km to inchesThere are also .inch and .to_inch methods, but since SU internal units are inches, these are almost never used (but are included, I think, for consistency).
Advertisement