DrawMeshFalseColors v6 bug

,

Have you noticed too that my two scripts posted above draw absolutely nothing in rendered display mode in V6 ? This looks like a V6 bug to me.

_
c.

Clement but in my case theres also nothing more than 10k boxes.

Hold on nothing at all boxes are calculated but display dont show them?

I rather read them i didnt fired them. Ill throw them in asap im on the go now.

@clement indeed in your script boxes are drawn right away instantly and are very quick in my case they kicks in quickly but i have rather slideshow when they appear :confused:

my 10k looks like that

Hi @D-W, @clement,

First, Mesh.Append is a different function in Rhino 6 than it was in Rhino 5. There is a lot more to do when appending meshes in Rhino 6, what with double precision vertices, n-gons, etc. So for sure, this function is slower in Rhino 6.

That said, appending 10,000 meshes to a base mesh one-by-one is super inefficient. This causes 10,000 memory re-allocations on each of the internal mesh arrays (there are several), plus all of the other calculations to ensure the meshes are merged property.

The solution is a better function to append meshes, which openNURB has and that I have exposed in RhinoCommon.

https://mcneel.myjetbrains.com/youtrack/issue/RH-47320

Your code updated to use this new method will look something like this:

meshes = List[Rhino.Geometry.Mesh](10 * 10 * 10)
for x in xrange(-100, 101, 10):
    for y in xrange(-100, 101, 10):
        for z in xrange(-100, 101, 10):
            vector = Rhino.Geometry.Vector3d(x,y,z)
            m_copy = mesh.Duplicate()
            m_copy.Transform(Rhino.Geometry.Transform.Translation(vector))
            meshes.Add(m_copy)
m = Rhino.Geometry.Mesh()
m.Append(meshes.ToArray()) #new!

With the override of Mesh.Append I’ve added, you’ll see better performance than what you saw in Rhino 5.

Note, this new override will appear in SR8. You should see an SR8 RC towards the end of this month.

– Dale

1 Like

I should add that if you have a plug-in that runs in both V5 and V6, you can use reflection to see if the new method exists.

For example, this handy extension method might be useful:

public static class ExtensionMethods
{
  public static void AppendMeshes(this Mesh mesh, IEnumerable<Mesh> meshes)
  {
    // Search for new method, added in Rhino 6.8, using reflection
    var type = typeof(Mesh);
    var method_info = type.GetMethod("Append", new Type[] { typeof(IEnumerable<Mesh>) });
    if (null != method_info)
    {
      // Append the Rhino 6.8 way
      var parameters = new object[] { meshes };
      method_info.Invoke(mesh, parameters);
    }
    else
    {
      // Append the old way
      foreach (var m in meshes)
      {
        mesh.Append(m);
      }
    }
  }
}

...

var disjoint_mesh = new Mesh();
disjoint_mesh.AppendMeshes(meshes);

– Dale

1 Like

I just noticed the same issue… thanks for getting on the fix. Computing normals does the trick for now, but I have another question/observation. In Rhino 6, the DrawMeshFalseColors method renders objects in a shaded fashion on my end. This is really unfortunate, and (in my mind) defeats the purpose of a falsecolor.

How do I fix this? @D-W is your nicely-emissive red box a Rhino 6 screen cap?

Thanks,

Jon

Hi Jon,
If there are no normals, I believe you will get an unlit false color mesh like the image on the right. This will be in SR8 which will be available next week. We will probably need to add options in the SDK for false color mesh drawing to apply lighting or not. I believe the lit false color look was requested by someone (@jeff may have better memory about this than me.)

Hi @Jon For now you have to draw mesh using DrawMeshShaded and set emissive material - yep weird but take @clement py script and there is good display material setup for this.

I feel the same about this.

This sounds like a bug… Can one of you provide me a simple example that shows the problem? I’d like something that I can run in V5 and V6, and where the results are different between the two versions… As far as I can tell, V6’s DrawShadedMeshes is correctly looking at the “lighting” aspects, and acting appropriately… Which is why I’d like an example.

Thanks,
-Jeff

I believe V5 didn’t look at the “lighting” aspects which is the difference. I assumed you made V6 pay attention to lighting based on a feature request.

V6 now has lit and unlit shading capabilities… Your common version of DrawMeshFalseColors turns lighting OFF… which is why, theoretically, things should work (i.e. draw as unlit, shaded meshes)… But apparently it’s not working, which is why I’d like an example.

-Jeff.

@jeff post no 9 of this topic…

@jeff the below generated the red box from my screenshot, which betrays the difference between Rhino 5 and 6 (current release).

var box = Mesh.CreateFromBox(new BoundingBox(new Point3d[] { new Point3d(0, 0, 0), new Point3d(1, 1, 1) }), 2, 2, 2);
for (var i = 0; i < box.Vertices.Count; i++) box.VertexColors.Add(Color.Red);
box.FaceNormals.ComputeFaceNormals(); // needed in current RH6 release (otherwise renders black)
box.Normals.ComputeNormals(); // ditto
e.Display.DrawMeshFalseColors(Box);

@stevebaer the proposed behavior in SR8 sounds good, thanks!

For the sake of clarity, and to soap box briefly :slight_smile:, I’m not talking about DrawShadedMesh. I’m talking about DrawMeshFalseColors. It is critical that the latter method NOT consider lighting and shadow, as the entire purpose of a falsecolor is to correlate data values to colors. Shading changes those colors and therefore renders the falsecolor useless. I’m sure there are many Rhino plug-ins that rely on falsecolor to display simulation results (lighting, finite element, etc.), so the emissive display should be the default.

@D-M yes one can create emissive materials but this only works for a single-colored object. :confused:

I don’t think that’s the issue I’m referring to… There are two issues being discussed, as far as I can tell… One has to do with back face normals vs. front face normals, which I’ve already fixed in SR8… The other has to do with whether or not DrawMeshFalseColors draws a lit or unlit shaded mesh. Again, I just want something I can quickly run on both versions… I don’t want to spend time throwing something together that just ends up being wrong and showing the wrong thing… It’s always best to get something from you guys (the users).

-J

@jeff hmm i didn’t noticed two issues here but maybe im wrong in my case thing is like in first post when i try to use DrawMeshFalseColors without normals i get black boxes - if colors per vertex are different some colors are displayed and black flicker occurs.

However i didn’t tried but if i’d like to draw bunch of planes instead of boxes there colud indeed appear backface normal issue.

And to be clear DrawMeshShaded is only form of workaround here.

Oh and indeed another issue that occured here was super long merging of meshes in v6 but @dale said that issue is under control now - not sure why youtrack gives me 404 -https://mcneel.myjetbrains.com/youtrack/issue/RH-47320

Which again, is why an example from you is important. The less I have to type and/or figure out what you’re trying to say, the bigger chance I have of seeing exactly what you’re seeing. My guess is that if I throw an example together that draws shaded meshes, it’s going to work.

-J

@jeff I don’t know if we agree whats happening here. Just put this to custom conduit and run it in v6 black box will appear:

protected override void PostDrawObjects(DrawEventArgs e)
{
  var mesh = new Mesh();

    mesh.Vertices.Add(new Point3d(0.5, 0.5, 0.5));
    mesh.Vertices.Add(new Point3d(0.5, 0.5, -0.5));
    mesh.Vertices.Add(new Point3d(0.5, -0.5, 0.5));
    mesh.Vertices.Add(new Point3d(0.5, -0.5, -0.5));
    mesh.Vertices.Add(new Point3d(-0.5, 0.5, 0.5));
    mesh.Vertices.Add(new Point3d(-0.5, 0.5, -0.5));
    mesh.Vertices.Add(new Point3d(-0.5, -0.5, 0.5));
    mesh.Vertices.Add(new Point3d(-0.5, -0.5, -0.5));

    mesh.Faces.AddFace(0, 1, 5, 4);
    mesh.Faces.AddFace(0, 4, 6, 2);
    mesh.Faces.AddFace(0, 2, 3, 1);
    mesh.Faces.AddFace(7, 3, 2, 6);
    mesh.Faces.AddFace(7, 6, 4, 5);
    mesh.Faces.AddFace(7, 5, 1, 3);

    for (var i = 0; i < mesh.Vertices.Count; i++)
        mesh.VertexColors.Add(Color.Red);

    e.Display.DrawMeshFalseColors(mesh);
}

My screen in the first post consists just of one big mesh which merged 10k of boxes - the same result you will get with above code.

Flicker will occur if instead of red color you’ll apply different colors per vertex.

Yep, I know…that’s due the absent of normals… which is not the problem I’m trying to produce… I’m trying to determine if a request to draw an unlit shaded mesh results in a lit shaded mesh.

Basically this:

image

I want something I can run in V5 and V6 that shows this.

-J

I think if you call mesh.Normals.ComputeNormals() on the mesh, you’ll get the shaded version in V6. I can double check it you need me to.

Ok, I’ll try that.

@jeff hmm i didn’t tried this that way - if you call in v5 DrawMeshFalseColors without normals you will get the same solid color on each face - if you’ll calculate normals for box you’ll get ‘lit’ version which is ok i think - to my thinking it is good that depends on ‘if’ normals exists but don’t know what others think.

To be precise box has to be unwelded to shade sides in case of calculating normals if it’s not side are also solid color.

ehh i tweaked different method of box :smiley: all kinds of DrawMeshFalseColors are always solid color on all sides and never get lit - so it should be that way as it was - lit only drawmeshshaded - drawmeshfalsecolors never lit :wink: