    

 ## On this page

  

 

 # Example 24 - C++ 

 Last update: 16.07.2025 

# <a class="anchor" id="ex24_s2"></a>C++

// CppStandaloneApplication.cpp : Defines the entry point for the console application.

 

\#include "stdafx.h"

\#include &lt;stdlib.h&gt;

\#include &lt;stdio.h&gt;

\#include &lt;iostream&gt;

\#include &lt;string&gt;

\#include &lt;ctime&gt;

\#include &lt;functional&gt;

\#include &lt;assert.h&gt;

\#include &lt;fstream&gt;

\#include &lt;iomanip&gt;

\#include &lt;vector&gt;

\#include &lt;cstdlib&gt;

 

// Note - .tlh files will be generated from the .tlb files (above) once the project is compiled.

// Visual Studio will incorrectly continue to report IntelliSense error messages however until it is restarted.

\#include "zosapi.h"

 

using namespace std;

using namespace [ZOSAPI](namespace_z_o_s_a_p_i.xhtml);

using namespace ZOSAPI_Interfaces;

 

void handleError(std::string msg);

void logInfo(std::string msg);

void finishStandaloneApplication(IZOSAPI_ApplicationPtr TheApplication);

 

int RunApplication()

{

 CoInitialize(NULL);

 

 // Create the initial connection class

 IZOSAPI_ConnectionPtr TheConnection(__uuidof([ZOSAPI\_Connection](class_z_o_s_a_p_i_1_1_z_o_s_a_p_i___connection.xhtml)));

 

 

 // Attempt to create a Standalone connection

 IZOSAPI_ApplicationPtr TheApplication = TheConnection-&gt;CreateNewApplication();

 if (TheApplication == nullptr)

 {

 handleError("An unknown error occurred!");

 return -1;

 }

 

 // Check the connection status

 if (!TheApplication-&gt;IsValidLicenseForAPI)

 {

 handleError("License check failed!");

 return -1;

 }

 if (TheApplication-&gt;Mode != ZOSAPI_Mode::ZOSAPI_Mode_Server)

 {

 handleError("Standlone application was started in the incorrect mode!");

 return -1;

 }

 

 

 // Add your custom code here...

 

 // creates a new API directory

 CreateDirectory(_bstr_t(TheApplication-&gt;SamplesDir + "\\\\API"), NULL);

 CreateDirectory(_bstr_t(TheApplication-&gt;SamplesDir + "\\\\API\\\\CPP"), NULL);

 

 // Set up primary optical system

 IOpticalSystemPtr TheSystem = TheApplication-&gt;CreateNewSystem(SystemType_NonSequential);

 ISDMaterialCatalogDataPtr catalog = TheSystem-&gt;SystemData-&gt;MaterialCatalogs;

 catalog-&gt;AddCatalog("Schott");

 _bstr_t sampleDir = TheApplication-&gt;SamplesDir;

 

 // Initializes NCE and loads surfaces

 // Inserts objects

 INonSeqEditorPtr TheNCE = TheSystem-&gt;NCE;

 for (int a = 1; a &lt;= 4; a++) TheNCE-&gt;InsertNewObjectAt(a);

 

 ISDMaterialCatalogDataPtr(TheSystem-&gt;SystemData-&gt;MaterialCatalogs)-&gt;AddCatalog("SCHOTT");

 

 // Gets reference to specific object

 ZOSAPI_Interfaces::INCERowPtr o1 = TheNCE-&gt;GetObjectAt(1);

 INCERowPtr o2 = TheNCE-&gt;GetObjectAt(2);

 INCERowPtr o3 = TheNCE-&gt;GetObjectAt(3);

 INCERowPtr o4 = TheNCE-&gt;GetObjectAt(4);

 INCERowPtr o5 = TheNCE-&gt;GetObjectAt(5);

 

 // Changes Object Type

 IObjectTypeSettingsPtr oType_1 = o1-&gt;GetObjectTypeSettings(ObjectType_SourceEllipse);

 o1-&gt;ChangeType(oType_1);

 o2-&gt;ChangeType((IObjectTypeSettingsPtr)o2-&gt;GetObjectTypeSettings(ObjectType_AsphericSurface2));

 o3-&gt;ChangeType((IObjectTypeSettingsPtr)o3-&gt;GetObjectTypeSettings(ObjectType_StandardLens));

 o4-&gt;ChangeType((IObjectTypeSettingsPtr)o4-&gt;GetObjectTypeSettings(ObjectType_DetectorColor));

 o5-&gt;ChangeType((IObjectTypeSettingsPtr)o5-&gt;GetObjectTypeSettings(ObjectType_DetectorRectangle));

 

 // Sets positions &amp; materials

 TheNCE-&gt;GetObjectAt(2)-&gt;XPosition = 1.5;

 TheNCE-&gt;GetObjectAt(2)-&gt;ZPosition = 9.99;

 TheNCE-&gt;GetObjectAt(2)-&gt;Material = "ABSORB";

 o3-&gt;YPosition = 1.5;

 o3-&gt;ZPosition = 8.99;

 o3-&gt;Material = "N-BK7";

 o4-&gt;ZPosition = 10;

 o5-&gt;RefObject = 4;

 o5-&gt;ZPosition = 1e-3;

 

 // Sets layout rays based on parameter number

 TheNCE-&gt;GetObjectAt(1)-&gt;GetObjectCell(ObjectColumn_Par1)-&gt;IntegerValue = 100;

 // Sets analysis rays based on object data column

 IObjectSourcesPtr sourcedata = o1-&gt;ObjectData;

 sourcedata-&gt;NumberOfAnalysisRays = (int)1E6;

 o1-&gt;GetObjectCell(ObjectColumn_Par10)-&gt;DoubleValue = 50;

 ((IObjectSourceEllipsePtr)o1-&gt;ObjectData)-&gt;GaussGY = 50;

 ((IObjectAsphericSurface2Ptr)o2-&gt;ObjectData)-&gt;MaxX = 0.5;

 ((IObjectAsphericSurface2Ptr)o2-&gt;ObjectData)-&gt;MaxY = 1;

 ((IObjectAsphericSurface2Ptr)o2-&gt;ObjectData)-&gt;IsRectangle = 1;

 ((IObjectDetectorColorPtr)o4-&gt;ObjectData)-&gt;XHalfWidth = 8.223;

 ((IObjectDetectorColorPtr)o4-&gt;ObjectData)-&gt;YHalfWidth = 2.565;

 ((IObjectDetectorColorPtr)o4-&gt;ObjectData)-&gt;NumberXPixels = 200;

 ((IObjectDetectorColorPtr)o4-&gt;ObjectData)-&gt;NumberYPixels = 150;

 

 double o5_x = 10.0;

 double o5_y = 12.23;

 ((IObjectDetectorRectanglePtr)o5-&gt;ObjectData)-&gt;XHalfWidth = o5_x;

 ((IObjectDetectorRectanglePtr)o5-&gt;ObjectData)-&gt;YHalfWidth = o5_y;

 ((IObjectDetectorRectanglePtr)o5-&gt;ObjectData)-&gt;NumberXPixels = 99;

 ((IObjectDetectorRectanglePtr)o5-&gt;ObjectData)-&gt;NumberYPixels = 100;

 

 // Changes face type and coating properties

 TheNCE-&gt;GetObjectAt(3)-&gt;CoatScatterData-&gt;GetFaceData(0)-&gt;FaceIs = FaceIsType_Absorbing;

 TheNCE-&gt;GetObjectAt(3)-&gt;CoatScatterData-&gt;GetFaceData(1)-&gt;FaceIs = FaceIsType_ObjectDefault;

 TheNCE-&gt;GetObjectAt(3)-&gt;CoatScatterData-&gt;GetFaceData(1)-&gt;Coating = "I.50";

 

 // changes scatter profile on face

 IObjectScatteringSettingsPtr o3_scatter = TheNCE-&gt;GetObjectAt(3)-&gt;CoatScatterData-&gt;GetFaceData(2)-&gt;CreateScatterModelSettings(ObjectScatteringTypes::ObjectScatteringTypes_Lambertian);

 o3_scatter-&gt;_S_Lambertian-&gt;ScatterFraction = 0.5;

 TheNCE-&gt;GetObjectAt(3)-&gt;CoatScatterData-&gt;GetFaceData(2)-&gt;ChangeScatterModelSettings(o3_scatter);

 TheNCE-&gt;GetObjectAt(3)-&gt;CoatScatterData-&gt;GetFaceData(2)-&gt;NumberOfRays = 2;

 

 // Removes pixel interpolation for the detector

 o4-&gt;TypeData-&gt;UsePixelInterpolation = false;

 

 // Setup and run the ray trace

 INSCRayTracePtr NSCRayTrace = TheSystem-&gt;Tools-&gt;OpenNSCRayTrace();

 NSCRayTrace-&gt;SplitNSCRays = false;

 NSCRayTrace-&gt;ScatterNSCRays = true;

 NSCRayTrace-&gt;UsePolarization = false;

 NSCRayTrace-&gt;IgnoreErrors = true;

 NSCRayTrace-&gt;SaveRays = false;

 NSCRayTrace-&gt;ClearDetectors(0);

 

 ISystemToolPtr baseTool = NSCRayTrace;

 baseTool-&gt;RunAndWaitForCompletion();

 

 // Reads in values from NCE for detector settings

 int obj = 4;

 double x_half = TheSystem-&gt;NCE-&gt;GetObjectAt(obj)-&gt;GetObjectCell(ObjectColumn_Par1)-&gt;DoubleValue;

 double y_half = TheSystem-&gt;NCE-&gt;GetObjectAt(obj)-&gt;GetObjectCell(ObjectColumn_Par2)-&gt;DoubleValue;

 double x_pixels = (double)TheSystem-&gt;NCE-&gt;GetObjectAt(obj)-&gt;GetObjectCell(ObjectColumn_Par3)-&gt;IntegerValue;

 double y_pixels = (double)TheSystem-&gt;NCE-&gt;GetObjectAt(obj)-&gt;GetObjectCell(ObjectColumn_Par4)-&gt;IntegerValue;

 

 // Creates a new detector viewer analysis reference

 IA_Ptr d4 = TheSystem-&gt;Analyses-&gt;New_Analysis(AnalysisIDM::AnalysisIDM_DetectorViewer);

 

 IAS_DetectorViewerPtr d4_settings = d4-&gt;GetSettings();

 d4_settings-&gt;Detector-&gt;SetDetectorNumber(4);

 d4_settings-&gt;ShowAs = DetectorViewerShowAsTypes_TrueColor;

 d4-&gt;ApplyAndWaitForCompletion();

 

 IAR_Ptr d4_results = d4-&gt;GetResults();

 IAR_DataGridRgbPtr d4_raw = d4_results-&gt;GetDataGridRgb(0);

 

 // Creates pointer arrays for RGB data channels

 float *rData = new float[(x_pixels * y_pixels)];

 float *gData = new float[(x_pixels * y_pixels)];

 float *bData = new float[(x_pixels * y_pixels)];

 

 // Reads values from detector color raw data

 // Prints RGB data into single file

 d4_raw-&gt;FillValues((x_pixels * y_pixels), rData, gData, bData);

 

 int Nx = d4_raw-&gt;Nx;

 int Ny = d4_raw-&gt;Ny;

 

 fstream textfile;

 string filepath = TheApplication-&gt;SamplesDir + "\\\\API\\\\CPP\\\\e24\_nsc\_detectors\_rgb.txt";

 textfile.open(filepath, fstream::trunc | ios::out);

 

 textfile &lt;&lt; "First column = smallest y coordinate.\\n";

 textfile &lt;&lt; "First row = smallest x coordinate.\\n\\n";

 

 textfile &lt;&lt; "R Channel Data:\\n";

 for (int i = 0; i &lt; Ny; i++) {

 for (int j = 0; j &lt; Nx; j++) {

 textfile &lt;&lt; setw(8) &lt;&lt; left &lt;&lt; rData[j + Nx*i] &lt;&lt; "\\t";

 }

 textfile &lt;&lt; endl;

 }

 textfile &lt;&lt; "\\nG Channel Data:\\n";

 for (int i = 0; i &lt; Ny; i++) {

 for (int j = 0; j &lt; Nx; j++) {

 textfile &lt;&lt; setw(8) &lt;&lt; left &lt;&lt; gData[j + Nx*i] &lt;&lt; "\\t";

 }

 textfile &lt;&lt; endl;

 }

 textfile &lt;&lt; "\\nB Channel Data:\\n";

 for (int i = 0; i &lt; Ny; i++) {

 for (int j = 0; j &lt; Nx; j++) {

 textfile &lt;&lt; setw(8) &lt;&lt; left &lt;&lt; bData[j + Nx*i] &lt;&lt; "\\t";

 }

 textfile &lt;&lt; endl;

 }

 

 textfile.close();

 

 // Changes default values for Detector Viewer

 // Plots the Incoherent Irradiance in False Color

 IA_Ptr d5 = TheSystem-&gt;Analyses-&gt;New_Analysis(AnalysisIDM_DetectorViewer);

 IAS_DetectorViewerPtr d5_set = d5-&gt;GetSettings();

 d5_set-&gt;Detector-&gt;SetDetectorNumber(5);

 d5_set-&gt;ShowAs = DetectorViewerShowAsTypes_FalseColor;

 d5-&gt;ApplyAndWaitForCompletion();

 IAR_Ptr d5_results = d5-&gt;GetResults();

 

 // This is the easiest way to retrieve the data via COM.

 // Create the array locally and pass it to the API to fill.

 IAR_DataGridPtr gi = d5_results-&gt;GetDataGrid(0);

 auto gid = gi-&gt;ValueData;

 long cols = gid-&gt;Cols, rows = gid-&gt;Rows;

 

 // Create the array. Note that if the array is too small, the application will crash when ReadData is called

 double *valuesAF = new double[cols * rows];

 

 gid-&gt;ReadData(cols * rows, valuesAF);

 long loop_ctr = 0;

 

 filepath = TheApplication-&gt;SamplesDir + "\\\\API\\\\CPP\\\\e24\_nsc\_detectors\_falsecolor.txt";

 textfile.open(filepath, fstream::trunc | ios::out);

 for (long j = 0; j &lt; rows; ++j) {

 for (long k = 0; k &lt; cols; ++k) {

 textfile &lt;&lt; valuesAF[loop_ctr++] &lt;&lt; '\\t';

 }

 textfile &lt;&lt; endl;

 }

 textfile.close();

 delete[] valuesAF;

 

 // saves current system in memory

 TheSystem-&gt;SaveAs((_bstr_t)TheApplication-&gt;SamplesDir + "\\\\API\\\\CPP\\\\e24\_nsc\_detectors.zos");

 

\#if defined(\_DEBUG)

 // keeps console open when in debug mode

 system("pause");

\#endif

 

 // Clean up

 finishStandaloneApplication(TheApplication);

 

 return 0;

}

 

void handleError(std::string msg)

{

 throw new exception(msg.c_str());

}

 

void logInfo(std::string msg)

{

 printf("%s", msg.c_str());

}

 

void finishStandaloneApplication(IZOSAPI_ApplicationPtr TheApplication)

{

 // Note - TheApplication will close automatically when this application exits, so this isn't strictly necessary in most cases

 if (TheApplication != nullptr)

 {

 TheApplication-&gt;CloseApplication();

 }

}

 

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)

{

 return RunApplication();

}

 

int _tmain(int argc, _TCHAR* argv[])

{

 return RunApplication();

}

[ZOSAPI.ZOSAPI\_Connection](class_z_o_s_a_p_i_1_1_z_o_s_a_p_i___connection.xhtml)

**Definition:** ZemaxService.cs:198



[ZOSAPI](namespace_z_o_s_a_p_i.xhtml)

The ZOSAPI namespace contains classes for initially connecting to zemax. See also ZOSAPI_Connection,...

**Definition:** IAS_FieldCurvatureAndDistortion.cs:5