Temp Face or Draw Method of the Tool Class

These days it seems like most of my API manipulations can be accomplished by rehashing previous code with some minor tweaks. In other words I don’t come across something totally new as much as I used to, I guess I’ve been at this a while now.

Today however, I am trying to build a tool which will allow me to select one of the edges of a face/group however the actual edges may or may not actually exist within the model. The points that define these edges are actually an array within my foundation’s attribute library. I can utilize these points to define the edges in question.

My first thought is to draw a temporary face/group given the points and then my tool can allow the user to select an edge. Once the selection is done the tool would then have to erase this temp group (face and edges), at that point I would then pass the vertices of that edge to the rest of my logic. My only reservation with this method is I don’t like inserting temp geometry as a rule of thumb since something could potentially disrupt the tool and then this temp group would be left abandoned within my model.

My other thought is to use the Draw method(s) of the Tool class and create the virtual face/edges this way. However there does not appear to be any way to select the geometry created by the Draw method of the Tool class since it really isn’t valid geometry within the model.

It’s highly possible that there is a something I’m missing here or even a third and better way to accomplish this edge selection process. I am very open to any thoughts or ideas anyone might have on the matter.

def onMouseMove(flags, x, y, view)
    point  = [x, y]
    do_something() if Geom.point_in_polygon_2D(point, @ary1, true)
end

john

1 Like

I think you are on to something here but I also need to be able to determine what edge the point is on and then send the vertices of that edge/line (two points) back to the rest of the program.

I’m digging through the Geom class right now to see if I can make this happen without actually having to construct (temporary) physical geometry within SketchUp.

I think the solution may be as simple as the on_line? method.

Just loop through all of the lines created by each pair of points and check for the on_line case being true.

The only problem will be edges that are collinear. I also need to determine that the point lays between the two endpoints of the line.

I’ve been using GL_TRIANGLE for each line, so I know the longest edge…

john

There is probably more than one way to solve this problem but the first method that comes to me is to create a vector for each endpoint (pointing towards the point in question). Then compare their directions.

If the point is between the two endpoints the vectors will always be in opposite directions. If the point is outside of the end points then the two vectors will be in the same direction.

There may be a more computationally lightweight solution that this, but I don’t see a ready made method so far in the class.

Here us what I have so far:

                ipt = @ip.position
				iptrans = ipt.transform(@Tot_trans)
				ipcheck = Geom::Point3d.new(iptrans.x, iptrans.y, 0)

				
				if Geom.point_in_polygon_2D(ipcheck, @pts_aligned, true)
					for index in 0 ... (@pts_aligned.size - 1)
						pt0 = @pts_aligned[index]
						pt1 = @pts_aligned[index+1]
						line01 = [pt0, pt1]

						if ipcheck.on_line?(line01)

							vec0 = ipcheck - pt0
							vec1 = ipcheck - pt1
							if (vec0.length > 0) && (vec1.length > 0)
								if !vec0.samedirection?(vec1)
								
									@pt0_trans = pt0
									@pt1_trans = pt1

									@pt0_draw = pt0.transform @Tot_trans_inv
									@pt1_draw = pt1.transform @Tot_trans_inv
								
									@Validledge = true	
									need_draw = true
									break
								
								end
							end

						end		
					end
				else
					@Validfnd = false
					@Validledge = false
				end

No temp geometry required, I like this.

1 Like

There is an entire thread on this coding problem in this category, which you started and I participated in …

You can use the PickHelper#pick_segment for this.

The pickhelper actually let you do two distinct things:

  • Pick entities in the model
  • Pick “virtual” segments and points using #pick_segment and test_point.

A long time ago I tried to make a visual reference of how the pick helper does: http://www.thomthom.net/thoughts/2013/01/pickhelper-a-visual-guide/

1 Like