Newbie: face destroyed after transformation ?!?!?

Greeting to all,

I’ve noticed that if I create a face, then transform one of the face’s vertices to a new location, the transformation does indeed work, the face changes shape on the screen just as I would expect, BUT it seems that the original face is deleted and replaced by a new one - I can no longer reference the original face by the name that I originally gave it. The code is down below.

NOTE that I think the following thread refers to this issue…

https://forums.sketchup.com/t/sketchup-face-reference-args-become-deleted-entity-after-transform-entities-call/34711

Although the face is indeed successfully transformed on the screen, I’ve noticed that the new face is assigned a new entityID after the vertex is transformed. So my question is … how do I reference a transformed face if the original face and face name are destroyed after the transformation? Do I have to keep track of the entityIDs? How do most folks handle such a situation?

THANKS!


    mod = Sketchup.active_model # Open model
    ent = mod.entities # All entities in model

    #Create the points of the square...
    pt1 = [0,0,0]
    pt2 = [5,0,0]
    pt3 = [5,5,0]
    pt4 = [0,5,0]

    #Draw the face, and name it "square"...
    square = ent.add_face pt1, pt2, pt3, pt4

   #Do the transformation...
   ptx = square.vertices[0]
   t = Geom::Transformation.new([1,0,0])
   ent.transform_entities(t, ptx)

    #But then the following generates a "reference to deleted Face" error...
    ptx = square.vertices[0]
  • How are you executing the code? Is it in a ruby file, if so inside a function definition or outside? Or do you run it on the Ruby Console?
  • I believe the transformation operation is not contained in the sample code.
  • ptx = square.vertices[0] returns a single vertex which is something different and not a point. Make sure to use appropriate names that fit well, otherwise misunderstandings will happen, code will be incorrectly used and cause errors. Also sloppy naming makes it harder to name other things later (for example a list of real points).

The reason a new face is made is because the moving of the one vertex likely splits the quad face into 2 triangular faces.

You need to take an array snapshot of the collection of faces before, and then subtract it from a set of faces afterward (being sure to removed any invalid faces.)

ents = Sketchup.active_model.active_entities
before = ents.grep(Sketchup::Face)
# do the transform here
new_faces = ents.grep(Sketchup::Face) - before
new_faces.reject! { |face| !face.valid? }
# now pick through the new faces to find the one you need

You can use the methods that are added by the Enumerable module to search arrays and other collections in Ruby.


FYI … you are referencing the face object as "square" not naming it. (In Object Oriented Programming these are specifically reference identifiers.)

Faces do not have a name property, but some complex objects like groups, instances and component definitions do.


How to post code in the forums … [How to] Colourize code on the forum? (wiki)

ADD: BTW, your snippet above does not show transforming a vertex.

If you enable the View > Hidden Geometry switch, you’ll see the softened edge that divides the two triangular post-transform faces.

Dan,

Thank you for your speedy, detailed and kind response! As someone who’s new to Ruby and OOP (but not to structural programming), I’ve some work ahead of me. I appreciate your pointing me in the right direction.

BTW, your snippet above does not show transforming a vertex. <<

DANG! Here’s what I left out…

ptx = square.vertices[0]
t = Geom::Transformation.new([1,0,0])
ent.transform_entities(t, ptx)

Take care

You can edit your previous post. Use the little edit pencil icon. It may be hidden by an ellipses (). Just click the ellipses to expand the post menu.

Aerilius,

Thank you for your response! I’m running the code either from the Ruby console or from Schreyer’s Ruby Code Editor.

You’re right; I stupidly left out the transformation code. I’ve added it to my response to Dan Rathbun, but I’ll try to add it to the original code.

I’m aware that naming conventions are very important. I just stripped everything down to the essentials for simplicity in my text.

Take care!

If you “Park” in the Ruby API subcategory, you’ll find many topic threads of interest.

There is a pinned topic there with lists for learning …

You should reassign this topic to that subcategory.
(Use the pencil icon to the right of the topic title above your initial post. Then use the category dropdown picklist. You can type a filter like Ruby or API to shrink the picklist.)

Okay with the transform I tested your code. I agree that we would not think the face reference should be lost, because the face is on the groundplane, and remains so after moving the vertex. So there is no triangulation happening.

I even tested inside an undo operation, but had the same result:

  def do_face
    mod = Sketchup.active_model # Open model
    ent = mod.entities # All entities in model
    mod.start_operation("Face Test")
      # Create the points of the square...
      pt1 = [0,0,0]
      pt2 = [5,0,0]
      pt3 = [5,5,0]
      pt4 = [0,5,0]

      # Draw the face, and name it "square"...
      square = ent.add_face pt1, pt2, pt3, pt4

      # Do the transformation...
      ptx = square.vertices[0]
      t = Geom::Transformation.new([1,0,0])
      ent.transform_entities(t, ptx)
    mod.commit_operation
    # But then the following generates a "reference to deleted Face" error...
    ptx = square.vertices[0]
  end

@thomthom Can you enlighten us ?

EDIT: It also does not matter if this is done inside a group context …

  def do_face
    mod = Sketchup.active_model # Open model
    ent = mod.entities # All entities in model
    mod.start_operation("Face Test")
      # Create the points of the square...
      pt1 = [0,0,2]
      pt2 = [5,0,2]
      pt3 = [5,5,2]
      pt4 = [0,5,2]

      grp = ent.add_group

      # Draw the face, and name it "square"...
      square = grp.entities.add_face pt1, pt2, pt3, pt4

      # Do the transformation...
      ptx = square.vertices[0]
      t = Geom::Transformation.new([1,0,0])
      grp.entities.transform_entities(t, ptx)
    mod.commit_operation
    # But then the following generates a "reference to deleted Face" error...
    ptx = square.vertices[0]
  end