How to control shadow in m_bShadeSurface?

hello, everyone. I am a rhino C++ Plugin Beginner.
i want to capture views and create its hbitmap in order to convert to cv::Mat.
in this processing ,I used CDisplayPipelineAttributes.m_bShadeSurface to replace render mesh for convenience.
but i don’t know how to control surface’s shadow , the image in opencv like this.
at this time, the view of rhino is
Please tell me what was missing in the process.
This is my test code, I will be grateful for any help you can provide.
code.cpp (2.2 KB)

As far as I can tell the only problem I see so far is that you’re starting with Wireframe display attributes…which contain zero shaded information… Shading requires all kinds of things, not the least of which are lights…

Why are you starting with the Wireframe display attributes? Why not the Shaded?

This is what you’re doing:


…this is what you should be doing/using:


Does that get you what you want/need?


thank you very much. it looks much better now.
Another problem is _ CDisplayPipelineAttributes.m_bShadeSurface;_ using default light ?
I still need to create meshes to use custom light?
Could you explain something to me?
I will be grateful for any help you can provide.

All of rhino’s display features and characteristics come from the “Display Attributes” …

If you go into Rhino’s Options->View->Display Modes, you will see all of the different display modes that Rhino defines by default (i.e. Wireframe, Shaded, X-Ray, Ghosted, Rendered, Technical, etc…)… All of those have predefined settings, and are what make the modes work the way they do. However, you can also create your own customized display mode(s) as well, and set them up to do whatever you want…Rhino’s built-in modes are simply predefined sets of CDisplayPipelineAttributes, that’s it…there is nothing special about them.

So for Wireframe, you will notice that there is no shading or lighting values (those don’t make sense in a Wireframe display).

For Shaded, you will see “shading” settings as well as lighting settings… Rhino’s “Shaded” display mode defines what is known as a “Custom Lighting Scheme”, and consists of 3 directional lights all defined with different directions and colors… So to answer your question… No, Shaded mode does not use the “default light”, it uses its default settings for lighting, which as I said, consists of 3 directional lights…

You can define your own set of display attributes and use those to get whatever effects or features you want or need. You can either start with a completely new set of attributes (i.e. the constructed values), and go through the tedious steps of setting the ones you want, or you can start with ones that are already defined by Rhino and then only change the ones you need.

For example: Suppose you wanted to render a frame so that it looks like Rhino’s “Rendered” display mode, but you don’t want shadows ON (which is Rendered mode’s default)… Then you would start with Rhino’s Rendered attributes, and then only make the appropriate changes… Like so:

CDisplayPipelineAttributes  MyRenderedMode(*CRhinoDisplayAttrsMgr::StdRenderedAttrs());

// Turn shadows OFF...
MyRenderedMode.m_bCastShadows = false;

// Now render the frame using MyRenderedMode as the attributes...
dp->DrawToDib(...., MyRenderedMode);

But before I go any further, it would be much better if you just told me what it is exactly you’re wanting/trying to do, what problem it is you’re trying to solve, and how you want to solve that problem using Rhino’s display pipeline… Then I’d be glad to explain to you how you could do it. I don’t understand your question about still needing to create meshes to use a custom light… that doesn’t make sense to me because the two are completely unrelated… so rather than go back and forth on specific things, I’d like to understand more about what it is you’re wanting to do.


My project is simulating real life light sources and combine common machine visual inspection processes.
I have to control light direction and location in rhino, but i have no idea.
i think rhino c++ sdk can help me in this project.
First, I learned about the rhino view, control the camera location and tracking object.
The next stage of my plan is to learn how to control the lights.
If there are any sample programs that can be used, please tell me.
I want to increase the surface texture in the future too. But there is still a lot of work to be done before this.
Thanks for your reply.

I’ll try to whip up a very simple example that moves lights, renders the frame, and then captures the results. I started typing an explanation for you, and 5 pages later of text I realized that source code is probably much better at explaining and showing how things work.

I’ll try to see if I can get something done over the weekend.


I apologize that it has taken so long to get back to you.
About moving the lights, rendering the frames, and then capturing the resulting , after a week of trying, I still have no way to control it.
It would be wonderful if you could show me sample code or provide me with any useful information.

Sorry, I got derailed on this and then the holidays crept up…and well… I dropped the ball on this one. Again sorry.

I will try to get you something before the end of this week.

Thanks for your patience on this.


Hello~@jeff :smile:
Thank you for considering my request.
If possible, I also wonder about how to get the normal vector of the mesh,because the normal vector will determine my color.
Any information would be appreciated.

I guess that could be interpreted in different ways… but what I think you’re asking is “how to get the normal vector for each polygon in a mesh?” …

All render meshes are stored as ON_Mesh objects… and at the very basic level, an ON_Mesh contains:

  • Vertexes
  • Normals
  • Texture Coordinates
  • Face information (which can vary)

If a mesh has normals, then for every vertex in the mesh there will be a corresponding normal…
If a mesh has texture coordinates, then for every vertex in the mesh there will be a corresponding texture coordinate.

To get at individual polygons (or faces), you need to determine the number of faces that exist, and act accordingly. Note: There can also exist “Face Normals”, which are computed using the vertices that make up the face/polygon…

For example: The following loop will iterate a mesh’s vertex list and obtain the normal and texture coordinate for each vertex.

ON_Mesh*   pMesh = Some Mesh....;
int   vertexCount = (pMesh ? pMesh->VertexCount() : 0);

for (int i = 0; i < vertexCount; i++)
  ON_3fVector   N;
  ON_TextureCoordinates  TC;

  if (pMesh->HasNormals())
    N = pMesh->m_N[i];
  if (pMesh->HasTextureCoordinates())
    TC = pMesh->m_TC[i];

If you want or need face normals, then it’s a similar process…

if (pMesh->HasFaceNormals())
  for (int i = 0; i < pMesh->FaceCount(); i++)
    ON_MeshFace  face = pMesh->m_F[i];
    ON_3fVector  faceNormal = pMesh->m_FN[i];


You should read through the header file containing ON_Mesh declaration (“opennurbs_mesh.h”)…as it provides all of the things you can do with a mesh and of course all of its interfaces.

Hopefully I’ve provided enough here to get you started…if not, please feel free to ask more questions.


I’m sorry to bother you again . @jeff
With your help , I completed a vector coloring of the mesh sphere .

and direction light setting like this
50099133_2133255760064368_5976078127707717632_n 50487774_1964002170561969_8307032655354920960_n
it’s get closer to my goals.
But displaying the rendering mode with BMP is the next difficulty.
The above image was captured using the Rhino user interface instead of drawing it through the display attributes.
Switching to rendering mode using the user interface causes the program to crash,I think it might be missing some important settings or unskilled about programming languages.
Is there any relevant c++ command code for reference?
Any information would be appreciated.:smile:
Thank you again for your generosity.