Problem adding polygon to mesh - again


#1

Well, I had got this to work in a previous version of the code.

But now I’ve had to re-sequence the code, and I’m stuck again, in just the same kind of way. I get an error when trying to add a polygon face to a Polygon mesh. It seems to be taking the x-value of a point as the index to the face in the mesh, and that clearly doesn’t work. But why is it doing that at all?

Here’s my first version code, which works:
RiverArch ellipses drawing.rb (7.2 KB)

This is line 178 that adds a polygon face to the mesh:

    mesh.add_polygon points1[i], points2[i], points2[i+1], points1[i+1]

It draws parts of an arch (for Newthinking2’s River Arch) - one face at a time, depending on the input parameters.

Here’s my second version code, which successfully creates and displays in the model as a component the two series of points1 and points2 that define the edges. But I can’t seem to create the mesh from it, not even the first face at the base of the arch section.
Draw arch v2.rb (9.5 KB)

I’m now trying again to add the faces to the mesh, and failing.

The mesh is defined as before:

  # Set up mesh for arch section
  num_pts = 2 * (max_slices + 1)
  num_poly = max_slices + 1
  # Now we have the points, create a polygon mesh to add faces
  mesh = Geom::PolygonMesh.new # num_pts, num_poly

i’ve tried with and without commenting out the parameters num_pts and num_poly.

Later when four points in the points1 and points2 series have been defined, I’m trying again to add points to the mesh, in line 247:

Here are the lines where it errors:

      if i > 0 && z1 < a1
        puts "Polygon points for slice i = #{i}: #{points1[i-1]}, #{points2[i-1]}, #{points2[i]}, #{points1[i]}"
        index = mesh.add_polygon points1[i-1], points2[i-1], points2[i], points1[i]
      end

Except for the shift in index from i to i-1 this appears to do the same as before, but doesn’t work.

And since I test for i > 0 it shouldn’t be ‘out of range’.

Before even getting to the third ‘slice’ (i = 2, n = 0) it dies with the following error:

`

draw_arch()
Polygon points for slice i = 1: [-12000.0, 0.0, 0.0], [-9150.0, 0.0, 0.0], [-9149.854789563884, 12.0, 60.0], [-11999.849999062488, 12.0, 60.0]
Error: #<ArgumentError: point index -11999 out of range>
/Users/JohnWMcC/Downloads/RiverArch/Draw arch v2.rb:247:in add_polygon' /Users/JohnWMcC/Downloads/RiverArch/Draw arch v2.rb:247:indraw_arch’

:in `' SketchUp:1:in `eval' `

The points look to be valid points (and where I expect them to be), and co-planar, but the mesh won’t add them.

I’m sure it’s something simple I’m overlooking, but for the moment at least, I just can’t see the difference between the code that works, and the code that doesn’t. And unfortunately, in my previous post, I didn’t detail what else (if anything) I did in changing from trying to add_faces_from_mesh to add_polygon that suddenly made it work.

Anyone able to help?


#2

I think you have to pass actual point3ds when using the polygon_mesh methods - equivalent three element arrays won’t work - unlike almost all other API methods !


#3

AARRGH!. I thought I’d tested that in the first version, and found that it didn’t matter.

But I see I left the code in v1 with pointsN arrays defined as Geom::Point3d, and I didn’t do that in v2.

Thanks, TIG. Will try that.

PS. Can I just set the points arrays up that way in the first place?

points1 = Geom::Point3d.new points2 = Geom::Point3d.new

or even
`
points1 = Geom::Point3d.new[]
points2 = Geom::Point3d.new[]

instead of

points1 = [] points2 = []
or do I have to do it every time I define a point with, y, z values?


Can I set up arrays that only contain points?
#4

Not to mention the annoying array start at 1 NOT 0 difference !
:wink:


#5

Can you comment on my PS to previous post?

I don’t know how to set up an array to contain Point3d values, or even if it is possible.


#6

Well, I’ve changed every reference when creating a new point from the form:

points1[i] = [x1, y1, z1]
(and the same for points2)

to
points1[i] = Geom::Point3d.new(x1, y1, z1)

then I get this error instead:

Polygon points for slice i = 178: (-5552.743106", 2127.6", 10638"), , (0", 2130", 10650"), (-5529.692577", 2130", 10650") Error: #<TypeError: no implicit conversion from nil to integer> /Users/JohnWMcC/Downloads/RiverArch/Draw arch v2.rb:247:inadd_polygon’
/Users/JohnWMcC/Downloads/RiverArch/Draw arch v2.rb:247:in `draw_arch’

:in `' SketchUp:1:in `eval'

`
So it is now producing most of the polygons, but stopping with too low a value of i which should go up to 198 or 199.

Maybe I’m missing one change of format somewhere, or accidentally creating an empty point and trying to add it. I can see it is happening where the z_height has just got above the apex of the lower part of the arch.

Can’t see it at the moment. The mesh may be getting filled, but it doesn’t show yet in the drawing.

TBC


#7

Looks like the method is expecting its entries starting from 1…
A normal array starts at 0…
So consider adjusting you code using [i+1] when affecting the mesh, to keep yourself one step ahead ?


#8

I don’t use the mesh index anywhere (and didn’t in previous code that worked). Just add polygons to it.

I must, I think, be inadvertently creating an empty point, and/or I’m not yet adding the mesh to the component.

Busy for a while now, but will come back to this later after eating.


#9

Yes, I have found a part of the code where one of points2[i-1] is not created, but adding the polygon expects a non-nil value there.

Now just have to track down why that’s happening, and fix it.


#10

Got it. At top of lower part of arch, I have to insert an extra ‘slice’ level if the apex isn’t on a slice boundary. I was (a) missing one point in the slice before that, and (b) putting the extra slice in one level too high.

Now working.

Tx for the pointer to requirement to use Point3d. I wonder why this is one of the very few places an array won’t work instead?


#11

It looks like the documentation is incomplete, or wrong. add_polygon appears to also accept a Array<Point3d, Array>. That is, an array of Pointd3d’s or an Array of 3-element Arrays. This is the data structure that the STL Importer uses to build its meshes.

Try this:

index = mesh.add_polygon([points1[i-1], points2[i-1], points2[i], points1[i]])

#12

Jim, thanks. I tried using index = mesh.add_polygon... but it didn’t make any difference, and I don’t need the index value anyway.

I am beginning to think that it may be a further missing data point that was the problem, not using Array instead of Point3d - I’ve found another place where I only created three points, but tried to add a polygon with four, one of which wasn’t there.

I’ve also got a problem in the very last three slices on the rounded inside or outside face where my logic is wrong, and i use the wrong points which aren’t co-planar, but too late to sort it tonight.

The logic works for a slanted or vertical plane face, but not for a rounded one. Will have to check it further.


#13

You may have logic errors in your code, but there is also a problem in the PolygonMesh docs and example which isn’t helping your debugging efforts.

It looks like the add_polygon method will accept a flat list of Point3d objects, or an Array of arrays. We’ll need to ask @thomthom to check the source code for clarification.


#14

(Moved to new topic --> Can I set up arrays that only contain points?)


#15

Geom::PolygonMesh.add_polygon can be invoked in four ways:

# An argument list of point-indicies:
add_polygon(index1, index2, index3)

# An array of point-indicies:
add_polygon([index1, index2, index3])

# An argument list of points:
add_polygon(point1, point2, point3)

# An array of points:
add_polygon([point1, point2, point3])

The input set isn’t limited to just 3 - though that is the minimum. In the case of there being less that 3 points the method will return 0 - which is an invalid index. The indices returned by this method start at 1.

At any point in the API when a Geom::Point3d or Geom::Vector3d is expected as a parameter one can substitute with an array of three numeric items.

(Similarly, the index returned by add_point also starts at 1 and 0 signify invalid index.)


#16

Does this raise an IndexError ?


#17

No - 0 is returned to signify failure.


#18

Hmmm… not Rubyish. Though workable.


#19

Except in this case where you can not substitute Arrays for Point3ds in your 3rd example. But you can just make an Array of Arrays.

The following will give you : #<ArgumentError: point index 0 out of range>.

# Does not work
pt1 = [0, 0, 0]
pt2 = [1, 0, 0]
pt3 = [1, 1, 0]
mesh = Geom::PolygonMesh.new
mesh.add_polygon(pt1, pt2, pt3)
# Does work
pt1 = [0, 0, 0]
pt2 = [1, 0, 0]
pt3 = [1, 1, 0]
mesh = Geom::PolygonMesh.new
mesh.add_polygon([pt1, pt2, pt3])

#20

Well, I’ve got it sorted now and this part works.

Mistake 1: point missing - caused add_polygon to fail. Now the point is there, it works.
Mistake 2: last but one point in the wrong place for rounded surface. Fixed. Now points are in plane, and the missing faces are created.

I’m now very confused, though, about whether I can use arrays instead of Point3d.

I tried replacing all my lines like
points1[i] = Geom::Point3d.new (x1, y1, z1)

with
points1[i] = [x1, y1, z1]

and replacing the lines
mesh.add_polygon points1[i-1], points2[i-1], points2[i], points1[i]

with
mesh.add_polygon [ points1[i-1], points2[i-1], points2[i], points1[i] ]

with the square brackets added to make it an array of arrays (points), but that still gave me the index error as before. Perhaps I missed a change of format somewhere, but I couldn’t get the latter format (just using arrays instead of Point3ds) to work.

So I’ve left it using the Point3d definition of all points1 and points2 - the other SHOULD work, but I don’t want to spend any more time now on the issue, now I have a working solution.

But I may come back to this later, and see if I CAN get the array format to work.