Alignment problem

This example GH script


has a small closed Brep I call a bullseye, a surface of rotation, and a set of points evenly distributed around the surface. What I’d like to do is position a bullseye at each point.

This script does that, but the distribution is not equal/even - some of the bullseyes are a bit off horizontally or vertically. They are not off much, but enough to be noticeable.

It’s not a precision problem - I cranked that up to Document Quality. The points are in the right place - I’ve looked at them in Top and Front views.

And there’s another/related problem: some of the bullseyes are reflected front to back:


These guys are facing both ways at the same time. Which seems quite weird to me - although in my real geometry the inside facing ones are inside the thickness of the final shape.

There must be someway to fix this, but I haven’t been able to find it.
misalignment.gh (116.8 KB)

Try with Paneling tools and recreate your base shape , doesn’t look good and make Grasshopper very slow.

misalignment_re.gh (9.9 KB)

After years of practice, I would think you be expert at this sort of thing by now. :wink: Why aren’t you using the usual SrfMorph or Sporph tricks for this?

The first thing I noticed is the Orient ‘A’ input is a list instead of a single XY plane corresponding to the ‘Bullseye’ shape? Then I noticed that the corners of the ‘Bullseye’ shape droop below the XY plane. But no matter what I tried, some of the oriented shapes appear to be missing their inside faces. So my conclusion is that the ‘Bullseye’ shape is malformed or corrupted somehow?


misalignment_2020Sep26a.gh (126.4 KB)

Replacing the ‘Bullseye’ shape with its bounding box works fine:

I constructed a better “Bullseye” shape which works fine.


bullseye_2020Sep26a.gh (124.3 KB)


misalignment_2020Sep26b.gh (240.2 KB)

I think some morphing to the surface would be better.

Hi Joseph - thanks (again) for your feedback. I did remember using those other methods - they were actually the first thing I tried. I was surprised when neither SrfMorph or Sporph worked in this case. Neither of them gave any error message or turned red, and they both returned just the surface without any bullseyes.

I agree that the bullseye is shaped peculiarly, but it is a closed BRep and I thought that Orient would place any closed Brep anywhere at all. I am aware of the drooping corners, and in my real script I account for this - and also that the bottom of the bullseye is basically flat - by orienting them on a scaled down surface that is slightly smaller than the outside one. This is similar to the method I used before with Sporph that “buries” the geometry under the outside surface.

The good news is your point about the reference plane solved my problem. For some reason - maybe because it was late at night - I didn’t get the fact that Orient’s A input wants just the plane of the mapped shape. So when I replaced the list of surface normals with the XY plane the results look great:

Of course there is still the issue of the flipped/mirrored geometry which I think is really weird, but in my case that doesn’t matter because all that craziness will be buried inside the final geometry because it has real thickness.


That’s exactly the look I wanted to achieve and I’m looking forward to seeing how the part looks in real life. I reckon it will take about 2 days to print.

Thanks again for getting me on the right track.

Thanks Seghier - since I am just a 3D printing hobbyist and not an architect I have never trued Panelling tools. But I can imagine how something like that would get around the problems I posted originally. Luckily the simple fix posted by Joseph worked well.

Thanks for that Joseph - it is a nicer result for sure. I’m sure it will take me some time for me to understand what you’ve done. I was afraid the drooping corners of my method would cause a nasty problem, so I was pleasantly surprised when a simple Cap worked just fine to create the closed Brep.

I’ve often thought about compiling a list of all the quirks (I can’t really call them bugs) I’ve found in GH over the years. GH is an amazing product, but like most things it’s quite a bit more complicated than it seems at first glance.

I don’t think anything is flipped or mirrored, it’s just missing the bottom/inside surface.

As to the bullseye shape, it doesn’t respond well to attempts to lop off those drooping corners using SDiff or Split Brep so I think it’s a “bad” closed brep.

I don’t remember how to use SrfMorph or Sporph and didn’t bother to look up our old efforts with them so am relearning now… slowly! Horizontal surface divisions appear to be uneven, concentrated (closer together) near the center, which is likely a result of how you created the surface, maybe the curve that you revolved?

Waiting patiently for results from SrfMorph, will post again soon.

I deconstructed your surface to get its seam, shortened it at both ends to match the reduced area used by your points, then rebuilt it to avoid the bunching up of horizontal isocurves in the middle of the new revolved surface. It’s easy to see that rebuilding the curve makes an obvious difference if you look at Divide Surface. All done before connecting the new surface to SrfMorph, of course, which is incredibly slow! Mistakes are very costly in terms of time…

Standing by again, waiting for results. Modifying params that control the bullseye shape is still possible too but I’m still using the one I posted.

Actually my bullseye has a bottom - all I did was Cap it and that yielded a closed Brep which is as good as it gets I think.

I created the target surface using a XZ plane Nurbs curve and Revolve Surface. My sense is this should be a very clean way of creating a nicely behaved surface. Of course there may be some hidden quirks there somewhere, but I’ve never encountered a problem with this type of surface.

There are 270 points at which to place the bullseyes, and yes, it does take a while to calculate all these and display them. It seems to me this would be a good place to employ multi-threading, but then I’m not the one who would have to write the code for this.

But that bottom gets lost on many of the oriented shapes. It is definitely not a good brep. If it were, I wouldn’t have done to the trouble of creating a better one.

Again, your revolved surface is not a “nice” one in the sense that horizontal isocurves are closer together near the middle of the surface (vertically). That can be fixed, as I described.

“I deconstructed your surface to get its seam, shortened it at both ends to match the reduced area used by your points, then rebuilt it”

That’s a totally different method from the one I used. What I did was to create a slightly smaller surface by XY scaling the original one by 0.995. Then, to eliminate the bottom row of bullseyes extending below the bottom of the surface, I culled out the first/bottom row of points. Doing this placed the bullseyes slightly below the surface of the real part and thus eliminated any corners of the bullseyes sticking out because they are flat on the bottom and are placed around a 2D curved surface.

That final requirement is how I was able to get the final shape for the target surface - I would have preferred one with more curvature, but doing that would require smaller bullseyes and that, in turn, would have made the print time even longer.

" It is definitely not a good brep."

Yes, I get your point, and I appreciate you showing how to make it a good one.

In all the work I’ve done so far I’ve found that most any problem I’ve encountered stops happening when the geometry is comprised of “closed Breps.” So when I discovered that capping my bullseye did that I figured I was home free. Obviously there is more to the story than this - so there’s yet another item for my quirks list.

The issue of the surface’s ISO curves not being evenly spaced is exactly the same as I’ve dealt with before. Naturally I was totally unaware of this issue until you pointed it out moths (years?) ago. But in this case I thought that having discrete target points with their individual X,Y,Z coordinates, rather than UV values relative to the surface, would make this a non issue.

I’m still not clear on what the relationship is between the mis-placed bullseyes and the true nature of the underlying surface. The mis-placements don’t seem to reflect the different amount of surface stretching my original surface has.

I’m beginning to think more seriously about creating that quirks list.

You avoided the issue similar to the way I did in my first post. Look at the disabled Contour code at the bottom of the canvas. By using those points (or your points) with Orient, isocurves are irrelevant. But I’m using SrfMorph now so they are very relevant again! They determine the size and shape of the morphed bullseyes. Your points are completely ignored in this model.

Voila. Notice the 16.4 minutes Profiler time for SrfMorph!


misalignment_2020Sep26c.gh (137.1 KB)

Also note some differences between Orient on the left and SrfMorph on the right. (below)

With Orient, all bulleyes are the same size so they are bunched together and overlap in the middle, and their back/inside surfaces are all flat instead of conforming to the surface as SrfMorph does. Spacing is perfectly even with SrfMorph because their sizes change slightly to match the isocurves.

You have to decide which horse you want to ride and build the model (and base surface) accordingly.

1 Like

It’s very easy to see using SDivide (Divide Surface) that isocurves will be farther apart at the top and bottom edges of your original surface (cyan group) vs. my rebuilt curve surface:


Thanks again Joseph for taking the time to explain what’s actually happening here. It looks like I may have to adopt your approach for using SrfMorph because my method results in Rhino exporting an STL file that has so many errors in it that no software known to man can fix them.

This is another one of those quirks I’ve encountered several times in the past, but I’ve always been able to resolve them by doing things like SUnion (for Breps), Mesh and/or JoinMesh for thing that Breps couldn’t work, or even Rhino’s Solid/Union command.

I’ll spare you the details, but none of those fixes seem to work at all. I added a Mesh Join function, but that created an STL file that was 1 GB in size - not very useful. When I added a Weld function after that my attempt to export it crashed Rhino and froze my system, which has never happened before. So I’m going to rework my GH script and see if the SrfMorph combined with your nice bullseye will allow me to create an STLfile that is actually printable.

These are the two experiments that confirmed for me that your bullseye was a bad Closed Brep. Both SDiff and Split Brep failed trying to operate on it:


bullseye_bad_2020Sep26a.gh (114.9 KB)

I’m going to try reducing the gaps in my last model by reducing the ‘falloff’ slider value and slightly increasing the wavelength in bullseye_2020Sep26a.gh. There might be other tricks as well.

Remember that to bury the bullseyes slightly below the surface you supply a small negative value to the ‘A’ input of the Domain component connected to the SrfMorph ‘W’ input, IIRC.

“your bullseye was a bad Closed Brep”

Yes it was! By simply substituting your method that generates the bullseye for mine I was (finally) able to produce an STL file that was sliceable and get a GCode file I can actually print.

Surprisingly the slicer loaded Rhino’s STL file as “Manifold”, which means it has no errors like disjoint/broken mesh triangles, inverted normals, etc. So I was pleasantly surprised that I didn’t have to do any corrections to the STL file that Rhino produced.

The STL file is 545 MB which is large, but not unheard of. The GCode file is 133 MB which is smaller than I expected. The estimated print time is 1 day 13 hours 27 min. which is pretty typical for the things I usually print.

I had some trouble achieving this result because some of the things I tried (various meshing options) caused Rhino to crash with the message “Reboot your system.” I didn’t do that; instead I just restarted Rhino and tried something else. But those efforts all failed for one reason or other. Finally I did reboot and got this lovely result:


That’s the result of slicing the STL file - it doesn’t get any better than that.

I think the key point in all this is (to paraphrase George Orwell) “why are some closed Breps better than other closed Breps?” And how are we to tell which are the good ones and which are not?

My (mental) quirks list is getting long.

The clues were there, it didn’t take long for me to reach that conclusion.


misalignment_2020Sep26d.gh (254.7 KB) (SrfMorph disabled)
bullseye_2020Sep26b.gh (127.9 KB)
http://islandcad.com/gh_forum/bullseye_vase2.3dm (336 Mb Rhino file)

This one (below) uses a bullseye shape that is three times larger so only 10 X 3 (30) instead of 30 X 9 (270). SrfMorph completes in only 2.6 minutes.


misalignment_2020Sep26e.gh (136.4 KB) (SrfMorph disabled)
bullseye_2020Sep26c.gh (127.4 KB)

Yup, I thought about making the bullseye larger, but I just thought the smaller ones would look better and be more interesting. Seeing that big one you showed just convinces me that my impression was correct. But, of course, different strokes for different folks.

After I get the print started I’ll go over the files you posted and try to understand what they do. I think the key difference is whether or not the mapped/morphed/oriented geometry is stretched/resized to fit the underlying surface. I’m thinking now that stretching the geometry would not be as nice as not stretching it, but I guess it depends on the actual shape of both the base surface and the mapped geometry. For base surfaces with more curvature I can see that stretching might be the only alternative that works.

I wonder if anyone knows (or cares) how to differentiate good Breps from bad ones.