Question

Hi all

I want to create a Sketchup tool for moving vertexes in a polygon (It is the same as move tool in sketchup ,except it just move vertex, not edge) . This polygon is in an array of polygon.

I created a "Tool" class, and when i pick the first vertex of one, move it to another position, and the appropriate polygon is created , replace the old polygon in array. But when i pick one vertex second time, ruby console display an error: reference to deleted Face

. Here is my class. I have implemented this tool in there function : onMouseMove, onLButtonDown, draw.

class MoveVertexPolygon
   # an array of polygon
   def gridview
      @gridview
   end
   def gridview=(g)
     @gridview=g
   end

   def initialize
     @polygon = nil
     @bSelected = false
     @arr_vertex = []
     @drawn = false
     @pos= -1
  end

def onLButtonDown(flags, x, y, view)
   #if user don't click any vertex before.
   if(@bSelected == false)
     ip = view.inputpoint x,y
     selected_x = ip.position.x.to_f
     selected_y = ip.position.y.to_f
     pt = Geom::Point3d.new(selected_x, selected_y, 0)

     #get appropriate polygon position in array of polygon 
     @pos = @gridview.getIndexByCoordinate(selected_x,selected_y)
     #reset array of vertex
     @arr_vertex.clear

     #get polygon with given position
     @polygon = @gridview.array_element[@res].polygon

     #select a vertex
     if(@polygon != nil && @polygon.valid? && @polygon.is_a? Sketchup::Face)
        type = @polygon.classify_point(pt)
        if(type == Sketchup::Face::PointOnVertex)
           i = 0
           while( i < @polygon.edges.length)
               @arr_vertex.push(@polygon.edges[i].vertices[0].position)
               if(pt == @polygon.edges[i].vertices[0].position)
                  @selectedVertexIndex = i
                  @bSelected = true
               end
              i = i + 1
           end;
        end
     end
  #if user selected vertex, move it to another position
  else
    @bSelected = false
    @drawn = false
    @gridview.array_element[@res].polygon = @polygon
  end
end

def onMouseMove(flags, x, y, view)
#if user select a vertex, then let's user choose a position of this vertex, display a temporary          #polygon
   if(@bSelected)
     @ip = view.inputpoint x,y
     view.invalidate
   end
end

def draw(view)
    if(@drawn == false)
       entities = view.model.entities

       temp_x = @ip.position.x.to_f
       temp_y = @ip.position.y.to_f
       pt = Geom::Point3d.new(temp_x, temp_y, 0)

       #delete all edges and face of @polygon
       i=0
       temp_array_edges = []
       while(i < @polygon.edges.length)
         temp_array_edges.push(@polygon.edges[i])
         i = i + 1
       end;
       len = temp_array_edges.length
       i=0
       while(i < len)
        entities.erase_entities temp_array_edges[i] 
        i = i + 1
       end;

       #draw polygon again
       @polygon = nil
       @arr_vertex[@selectedVertexIndex] = pt
       @polygon = entities.add_face @arr_vertex

     end
end

Error said that @polygon is Deleted Face.

Thanks for your helping

Was it helpful?

Solution

Instead of erasing and recreating the face constantly, simply transform the vertex to it's new position. entities.transform_by_vectors will let you do that. http://www.sketchup.com/intl/en/developer/docs/ourdoc/entities.php#transform_by_vectors

And if you want display anything temporarily while using your tool, use view.draw to draw to the viewport.

You really should avoid doing anything other than drawing to the viewport in the draw event.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top