Sketchup Ruby API对已删除面的引用

Sketchup Ruby API对已删除面的引用,ruby,sketchup,Ruby,Sketchup,大家好 我想创建一个Sketchup工具来移动多边形中的顶点(它与Sketchup中的移动工具相同,只是它只移动顶点,而不是边)。此多边形位于多边形数组中 我创建了一个“工具”类,当我拾取其中一个顶点的第一个顶点时,将其移动到另一个位置,然后创建相应的多边形,替换阵列中的旧多边形。但当我第二次拾取一个顶点时,ruby控制台显示一个错误:引用已删除的面。 这是我的班级。我在那里实现了这个工具的功能:onMouseMove、onLButtonDown、draw class MoveVertexPol

大家好

我想创建一个Sketchup工具来移动多边形中的顶点(它与Sketchup中的移动工具相同,只是它只移动顶点,而不是边)。此多边形位于多边形数组中

我创建了一个“工具”类,当我拾取其中一个顶点的第一个顶点时,将其移动到另一个位置,然后创建相应的多边形,替换阵列中的旧多边形。但当我第二次拾取一个顶点时,ruby控制台显示一个错误:引用已删除的面

。 这是我的班级。我在那里实现了这个工具的功能: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
类移动顶点多边形
#多边形数组
def网格视图
@网格视图
结束
def gridview=(g)
@gridview=g
结束
def初始化
@多边形=零
@bSelected=false
@arr_顶点=[]
@绘制=假
@位置=-1
结束
def ONLBUTDOWN(标志、x、y、视图)
#如果用户以前没有单击任何顶点。
如果(@bSelected==false)
ip=视图输入点x,y
所选位置=ip.position.x.至
所选y=ip.position.y.至
pt=Geom::Point3d.new(选中的x,选中的y,0)
#在多边形数组中获取适当的多边形位置
@pos=@gridview.getIndexByCoordinate(已选择x,已选择y)
#重置顶点数组
@arr_顶点清除
#获取给定位置的多边形
@多边形=@gridview.array_元素[@res]。多边形
#选择一个顶点
if(@polygon!=nil&&&@polygon.valid?&&&@polygon.is_a?Sketchup::Face)
类型=@polygon.classify_点(pt)
如果(类型==Sketchup::Face::PointOnVertex)
i=0
而(i<@polygon.edges.length)
@arr_vertex.push(@polygon.edges[i]。顶点[0]。位置)
if(pt=@polygon.edges[i]。顶点[0]。位置)
@selectedVertexIndex=i
@bSelected=true
结束
i=i+1
结束;
结束
结束
#如果用户选择了顶点,请将其移动到其他位置
其他的
@bSelected=false
@绘制=假
@gridview.array_元素[@res].polygon=@polygon
结束
结束
def onMouseMove(标志、x、y、视图)
#如果用户选择一个顶点,那么让用户选择该顶点的位置,显示一个临时的#多边形
如果(@bSelected)
@ip=视图输入点x,y
使无效
结束
结束
def绘图(视图)
如果(@draw==false)
实体=view.model.entities
temp_x=@ip.position.x.to\u f
temp\u y=@ip.position.y.to\u f
pt=Geom::Point3d.new(温度x,温度y,0)
#删除@polygon的所有边和面
i=0
临时数组_边=[]
而(i<@polygon.edges.length)
临时数组边缘推送(@polygon.edges[i])
i=i+1
结束;
len=临时数组长度
i=0
而(我
错误说明@polygon已被删除


感谢您的帮助

只需将顶点变换到新位置即可,而无需不断擦除和重新创建人脸<代码>实体。通过向量变换可以实现这一点。

如果您想在使用工具时临时显示任何内容,请使用
view.draw
绘制到视口


您确实应该避免在
draw
事件中除了绘制视口之外的任何操作。

此处需要更多信息。完整的错误信息是什么?当
@polygon
是一个被删除的面时?同样,你使用批量方法来擦除循环中的个别元素:
实体。擦除实体临时数组边[i]
,为什么不批量擦除所有内容:
实体。擦除实体(临时数组边)
?我不知道你对这个工具的要求是什么,但是我制作了一个用于操纵顶点的工具:(不是免费的)为什么要在工具的
draw
事件中擦除实体?该事件用于将OpenGL指令绘制到视口。它通常一秒钟调用多次,擦除实体或创建实体都没有意义。@thom:full错误消息:error:#在draw方法中的行代码:while(i<@polygon.edges.length)。我的工具帮助用户移动多边形的一个顶点(只是顶点,而不是边或面)。这就像Sketchup中的移动工具。其操作与Sketchup移动工具操作相同(通过左键单击并拖动鼠标选择顶点,将显示相应的临时多边形,当用户再次左键单击时,将显示具有新顶点的多边形(拖放)。