(C++) Some issues when creating black skin with few items


From all the resources I found around (specially @dale’s) I’ve made a skin (called Black Skin) that does the following:

  • Replace main view names with 3D View, Axial, Coronal, Sagittal
  • Set all views to rendered mode
  • Set black background color in rendered mode
  • Hide toolbars, control bars, menu bar and status bar
  • Set gumball on

Though, I’m not sure if I’m doing it properly, because when opening the skin it takes quite some time until Rhino is set up this way. I also see for some seconds the standard Rhino interface before things are hidden and background set to rendered black solid color.

I’m doing all the changes in a watcher derived from CRhinoIsIdle after an event of type OnInitRhino. As the steps heavily involve modifying the CRhinoDoc active document, I believe I can’t directly put them in a CRhinoEventWatcher OnInitRhino event, neither in OnLoadPlugIn(), can I?
On top of that, please tell me if some of these steps could be done more properly or efficiently with other Rhino sdk functions or in other places in code.

Here’s the full project

BlackSkin.zip (56.3 KB)
BlackSkinHandler.zip (33.6 KB)

and here’s the particularly relevant code doing the changes inside the idle watcher:

///////////// Watcher

class BlackSkinHandlerWatcher : public CRhinoEventWatcher
   BlackSkinHandlerWatcher() = default;
   ~BlackSkinHandlerWatcher() = default;

   void OnInitRhino(CRhinoApp& app);

///////////// Idle Watcher

class BlackSkinHandlerIdleWatcher : public CRhinoIsIdle
   ~BlackSkinHandlerIdleWatcher() = default;
   virtual void Notify(const class CRhinoIsIdle::CParameters& params);
///////////// Watcher

void BlackSkinHandlerWatcher::OnInitRhino(CRhinoApp& app) {
	BlackSkinHandlerPlugIn().m_initiatedRhino = true;

///////////// Idle Watcher

	: CRhinoIsIdle(BlackSkinHandlerPlugIn().PlugInID())

void BlackSkinHandlerIdleWatcher::Notify(const CRhinoIsIdle::CParameters& params)
	ON_wString scheme = RhinoApp().RegistrySchemeName();
	if (BlackSkinHandlerPlugIn().m_initiatedRhino) // If Rhino has started
		BlackSkinHandlerPlugIn().m_initiatedRhino = false;
		if (scheme.CompareNoCase(L"Scheme: BlackSkin") == 0) // If Black Skin scheme
			CRhinoDoc* doc = RhinoApp().ActiveDoc();
			if (doc) 
				// Replace view names with 3D View, Axial, Coronal, Sagittal
				ON_3dmView views[4];
				doc->FindView(L"Perspective", views[0]);
				doc->FindView(L"Top", views[1]);
				doc->FindView(L"Front", views[2]);
				doc->FindView(L"Right", views[3]);

				views[0].m_name = L"3D View";
				views[1].m_name = L"Axial";
				views[2].m_name = L"Coronal";
				views[3].m_name = L"Sagittal";


				doc->ReplaceModelViews(4, views);

				// Set all views to rendered mode
				ON_SimpleArray<CRhinoView*> standardViews;
				const int standardViewCount = doc->GetViewList(standardViews, true, false);
				for (int i = 0; i < standardViewCount; i++) 
					CRhinoView* view = standardViews[i];
					if (nullptr != view) 
						CRhinoViewport& vp = view->ActiveViewport();
						const CDisplayPipelineAttributes* pStdAttrs;
						pStdAttrs = CRhinoDisplayAttrsMgr::StdRenderedAttrs();

				// Set black background color in rendered mode
				DisplayAttrsMgrListDesc* pAttrsDesc = CRhinoDisplayAttrsMgr::FindDisplayAttrsDesc(ON_StandardDisplayModeId::Rendered);
				if (pAttrsDesc) 
					CDisplayPipelineAttributes* pAttrs = pAttrsDesc->m_pAttrs;
					if (pAttrs) 
						pAttrs->m_eFillMode = EFrameBufferFillMode::FBFM_SOLID_COLOR;
						pAttrs->m_SolidColor = ON_Color::Black;

				// Hide toolbars, control bars, menu bar and status bar
				RhinoApp().HideWindowBars(0x00000002); //HWB_MENU_BAR
				RhinoApp().HideWindowBars(0x00000004); //HWB_STATUS_BAR


				//Set gumball on
				RhinoApp().RunScript(doc->RuntimeSerialNumber(), L"_-Gumball _On _Enter", 0);

Thank you,

Hi @Pablo_Garcia-Amorena,

The first time you Rhino with a new scheme, it can take a while for Rhino to open. After that, it should open as fast as normal Rhino.

If you dont’ want to see Rhino’s default viewports, maybe you can hid them behind a splash screen. Also have a default template file with black-backround Render mode might help. You might also consider starting Rhino minimized (shortcut) and then restoring the view in your idle handler.

As far as settings, you might consider doing this:

CRhinoAppAppearanceSettings settings = RhinoApp().AppSettings().AppearanceSettings();
// Turn stuff off

– Dale

Hi @dale ,

Is it possible to make the splash screen stay more time than what it normally does? How can I control that?

How do I do this? It looks like linking the skin desktop shortcut to a default template file.

This would be helpful indeed. Is there a way to start Rhino minimized from tools inside the Rhino SDK?



Here is an excerpt from how we start Rhino hidden from the user. We later show the window using a pinvoke call.

We use a ProcessStartInfo() object to change the processes behavior on startup.

1 Like