    

 ## On this page

  

 

 # Example 21 - C++ 

 Last update: 16.07.2025 

# <a class="anchor" id="ex21_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;sstream&gt;

\#include &lt;iomanip&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;

 }

 

 IOpticalSystemPtr TheSystem = TheApplication-&gt;PrimarySystem;

 

 // Add your custom code here...

 

 // creates new directory

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

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

 

 // Create a new non-sequential file

 TheSystem-&gt;New(false);

 TheSystem-&gt;MakeNonSequential();

 // Add new catalog MISC

 TheSystem-&gt;SystemData-&gt;MaterialCatalogs-&gt;AddCatalog("MISC");

 // Set Wave #1 to 0-&gt;47 micron

 TheSystem-&gt;SystemData-&gt;Wavelengths-&gt;GetWavelength(1)-&gt;Wavelength = 0.47;

 // Use lumens as the source unit

 TheSystem-&gt;SystemData-&gt;Units-&gt;SourceUnits = ZemaxSourceUnits_Lumens;

 

 // Add 4 more objects

 INonSeqEditorPtr TheNCE = TheSystem-&gt;NCE;

 TheNCE-&gt;AddObject();

 TheNCE-&gt;AddObject();

 TheNCE-&gt;AddObject();

 TheNCE-&gt;AddObject();

 

 // Set 1st object as a Source File

 INCERowPtr Object_1 = TheNCE-&gt;GetObjectAt(1);

 IObjectTypeSettingsPtr Typeset_SourceFile = Object_1-&gt;GetObjectTypeSettings(ObjectType_SourceFile);

 Typeset_SourceFile-&gt;FileName1 = "RAYFILE\_LB\_T67C\_100K\_190608\_ZEMAX.DAT";

 Object_1-&gt;ChangeType(Typeset_SourceFile);

 Object_1-&gt;GetObjectCell(ObjectColumn_Par1)-&gt;IntegerValue = 5;

 Object_1-&gt;GetObjectCell(ObjectColumn_Par2)-&gt;IntegerValue = 1000;

 Object_1-&gt;GetObjectCell(ObjectColumn_Par3)-&gt;DoubleValue = 2.485572;

 Object_1-&gt;GetObjectCell(ObjectColumn_Par8)-&gt;DoubleValue = 0.47;

 Object_1-&gt;GetObjectCell(ObjectColumn_Par9)-&gt;DoubleValue = 0.47;

 

 // Edit source data of object 1

 // SourcesData includes all the settings in Object Properties &gt; Sources

 Object_1-&gt;SourcesData-&gt;PrePropagation = -0.2;

 Object_1-&gt;SourcesData-&gt;ArrayType = ArrayMode_Rectangular;

 Object_1-&gt;SourcesData-&gt;ArrayNumberX = 5;

 Object_1-&gt;SourcesData-&gt;ArrayNumberY = 5;

 

 // Set 2nd object as CAD Part: STEP/IGES/SAT

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

 IObjectTypeSettingsPtr Typeset_CADPartSTEPIGESSAT = Object_1-&gt;GetObjectTypeSettings(ObjectType_CADPartSTEPIGESSAT);

 Typeset_CADPartSTEPIGESSAT-&gt;FileName1 = "LB\_T67C\_190608\_GEOMETRY.STEP";

 Object_2-&gt;ChangeType(Typeset_CADPartSTEPIGESSAT);

 

 // Set Rays Ignore Object = Always for object 2

 // TypeData includes all settings in Object Properties &gt; Type

 Object_2-&gt;TypeData-&gt;RaysIgnoreObject = RaysIgnoreObjectType_Always;

 

 // Set 3rd object as Cylinder Volume

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

 IObjectTypeSettingsPtr Typeset_CylinderVolume = Object_3-&gt;GetObjectTypeSettings(ObjectType_CylinderVolume);

 Object_3-&gt;ChangeType(Typeset_CylinderVolume);

 // Set positions, material and parameters

 Object_3-&gt;GetObjectCell(ObjectColumn_ZPosition)-&gt;DoubleValue = 0.8;

 Object_3-&gt;GetObjectCell(ObjectColumn_Material)-&gt;Value = "PMMA";

 Object_3-&gt;GetObjectCell(ObjectColumn_Par1)-&gt;DoubleValue = 1.2;

 Object_3-&gt;GetObjectCell(ObjectColumn_Par2)-&gt;DoubleValue = 0.1;

 Object_3-&gt;GetObjectCell(ObjectColumn_Par3)-&gt;DoubleValue = 1.2;

 

 // Make Face 1 of object 3 has Lambertian scattering properties

 // To set scatter properties, you need to first create "ScatteringSettings" by "CreateScatterModelSettings()" method.

 // And then assign is to object 3 by ChangeScatterModelSettings().

 IObjectScatteringSettingsPtr ScatType_Lam = Object_3-&gt;CoatScatterData-&gt;GetFaceData(1)-&gt;CreateScatterModelSettings(ObjectScatteringTypes_Lambertian);

 ScatType_Lam-&gt;_S_Lambertian-&gt;ScatterFraction = 1;

 Object_3-&gt;CoatScatterData-&gt;GetFaceData(1)-&gt;ChangeScatterModelSettings(ScatType_Lam);

 Object_3-&gt;CoatScatterData-&gt;GetFaceData(1)-&gt;NumberOfRays = 1;

 

 // Make object 3 a volume scattering material

 // VolumePhysicsData includes all settings in Object Properties &gt; VolumePhysics.

 // Use Photoluminescence model

 Object_3-&gt;VolumePhysicsData-&gt;Model = VolumePhysicsModelType_PhotoluminescenceModel;

 IVMPS_PhotoluminscenceModelPtr Photo_setting = Object_3-&gt;VolumePhysicsData-&gt;ModelSettings-&gt;_S_PhotoluminescenceModel;

 // Use standard algorithm

 Photo_setting-&gt;BasicAlgorithm = false;

 // Set absorb, emission and quantum yield files

 Photo_setting-&gt;AbsorptionFile = "\_sample\_3.ZAS";

 Photo_setting-&gt;EmissionFile = "\_sample\_3.ZES";

 Photo_setting-&gt;QuantumYield = "\_sample\_3.ZQE";

 // Set efficiency spectrum to quantum yield

 Photo_setting-&gt;EfficiencySpectrum = EfficiencySpectrumType_QuantumYield;

 // Set photoluminescence parameters

 Photo_setting-&gt;ExtinctionCoefficient = 1e+05;

 Photo_setting-&gt;ExtinctionWavelength = 0.47;

 Photo_setting-&gt;PLDensity = 3.1e+017;

 // Set model to ignore mie scattering

 Photo_setting-&gt;ConsiderMieScattering = false;

 

 // Set 4th object as Standard Lens

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

 IObjectTypeSettingsPtr Typeset_StandardLens = Object_4-&gt;GetObjectTypeSettings(ObjectType_StandardLens);

 Object_4-&gt;ChangeType(Typeset_StandardLens);

 // Set positions

 Object_4-&gt;GetObjectCell(ObjectColumn_ZPosition)-&gt;DoubleValue = 0.9;

 // To set solve for any cell, you need to first create a "ISolveData" by "CreateSolveType()" method.

 // And then assign it to the cell.

 ISolveDataPtr Solve_ObjPick = Object_4-&gt;GetObjectCell(ObjectColumn_Material)-&gt;CreateSolveType(SolveType_ObjectPickup);

 Solve_ObjPick-&gt;_S_ObjectPickup-&gt;Object = 3;

 // Set parameters

 Object_4-&gt;GetObjectCell(ObjectColumn_Material)-&gt;SetSolveData(Solve_ObjPick);

 Object_4-&gt;GetObjectCell(ObjectColumn_Par3)-&gt;DoubleValue = 1.2;

 Object_4-&gt;GetObjectCell(ObjectColumn_Par4)-&gt;DoubleValue = 1.2;

 Object_4-&gt;GetObjectCell(ObjectColumn_Par5)-&gt;DoubleValue = 1.2;

 Object_4-&gt;GetObjectCell(ObjectColumn_Par6)-&gt;DoubleValue = -1.2;

 Object_4-&gt;GetObjectCell(ObjectColumn_Par8)-&gt;DoubleValue = 1.2;

 Object_4-&gt;GetObjectCell(ObjectColumn_Par9)-&gt;DoubleValue = 1.2;

 

 // Set 5th object as Detector Color

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

 IObjectTypeSettingsPtr Typeset_DetectorColor = Object_5-&gt;GetObjectTypeSettings(ObjectType_DetectorColor);

 Object_5-&gt;ChangeType(Typeset_DetectorColor);

 // Set positions, material and parameters

 Object_5-&gt;GetObjectCell(ObjectColumn_ZPosition)-&gt;DoubleValue = 7;

 Object_5-&gt;GetObjectCell(ObjectColumn_Material)-&gt;Value = "ABSORB";

 Object_5-&gt;GetObjectCell(ObjectColumn_Par1)-&gt;DoubleValue = 5;

 Object_5-&gt;GetObjectCell(ObjectColumn_Par2)-&gt;DoubleValue = 5;

 Object_5-&gt;GetObjectCell(ObjectColumn_Par3)-&gt;IntegerValue = 150;

 Object_5-&gt;GetObjectCell(ObjectColumn_Par4)-&gt;IntegerValue = 150;

 Object_5-&gt;GetObjectCell(ObjectColumn_Par6)-&gt;IntegerValue = 4;

 Object_5-&gt;GetObjectCell(ObjectColumn_Par7)-&gt;IntegerValue = 3;

 

 // Open NSC Ray Trace tool and turn on Scatter NSC Rays and Ignore Errors

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

 RayTraceControl-&gt;SplitNSCRays = false;

 RayTraceControl-&gt;ScatterNSCRays = true;

 RayTraceControl-&gt;UsePolarization = false;

 RayTraceControl-&gt;IgnoreErrors = true;

 RayTraceControl-&gt;SaveRays = false;

 

 // Trace rays and report the progress when it's running.

 // Note that, instead an RunAndWaitCompletion(), Run() is used so that

 // the code will just go on without waiting the tracing finishs.

 // We will check the progress of tracing by a while loop.

 // You can check the properties "Progress", which is percentage integer data (1-100)

 cout &lt;&lt; "Starting Tracing... ";

 RayTraceControl-&gt;ClearDetectors(0);

 // Run() is defined in ISystemTool interface.

 // To use this method, we need to cast to ISystemTool.

 ISystemToolPtr baseTool = RayTraceControl;

 baseTool-&gt;Run();

 while (baseTool-&gt;Progress != 100)

 {

 Sleep(1000);

 cout &lt;&lt; "\\b\\b\\b\\b" &lt;&lt; std::setfill(' ') &lt;&lt; std::setw(3) &lt;&lt; baseTool-&gt;Progress &lt;&lt; "%";

 }

 baseTool-&gt;Close();

 cout &lt;&lt; "\\nFinished!" &lt;&lt; endl;

 

 // Open two detector viewers for showing results in angle space and position space

 // Detector Viewer has its own settings interface: IAS\_DetectorViewer.

 // Note that not all analyses have a specific settings interface.

 I_AnalysesPtr TheAnalysis = TheSystem-&gt;Analyses;

 IA_Ptr Det1 = TheAnalysis-&gt;New_DetectorViewer();

 IAS_DetectorViewerPtr Det_Set1 = Det1-&gt;GetSettings();

 Det_Set1-&gt;ShowAs = DetectorViewerShowAsTypes_TrueColor;

 Det_Set1-&gt;Smoothing = 3;

 Det1-&gt;ApplyAndWaitForCompletion();

 

 IA_Ptr Det2 = TheAnalysis-&gt;New_DetectorViewer();

 IAS_DetectorViewerPtr Det_Set2 = Det2-&gt;GetSettings();

 Det_Set2-&gt;ShowAs = DetectorViewerShowAsTypes_TrueColor;

 Det_Set2-&gt;Smoothing = 3;

 Det_Set2-&gt;DataType = DetectorViewerShowDataTypes_AngleSpace;

 Det2-&gt;ApplyAndWaitForCompletion();

 

 

 TheSystem-&gt;SaveAs(TheApplication-&gt;SamplesDir + "\\\\API\\\\CPP\\\\e21\_White\_LED\_Phosphor.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