ENCY CAM IPC — Project / Technologist Domain
This document covers the CAMIPC variants of the Project / Technologist interfaces. CAMIPC is used when an extension communicates with the ENCY CAM process across a process boundary (inter-process communication).
For a full description of each interface's purpose, properties, and usage patterns,
see the CAMAPI reference: ../api/project.md.
This document focuses exclusively on what differs in the IPC layer.
Key difference: TExecuteContext
Every IPC method that crosses the process boundary takes a [in, out] struct TExecuteContext*
parameter. The context carries the call's execution state, error information, and
cancellation token. In the .NET helper layer this is handled transparently — you
do not construct or pass TExecuteContext manually.
In raw IDL / COM you pass a pointer to a stack-allocated TExecuteContext on every
call:
// IDL style (direct COM, not recommended for new code)
TExecuteContext ctx = {};
string id = project->GetId(&ctx);
With the .NET helper the context is managed inside ComWrapper.Invoke / InvokeAndWrap,
so the call sites look identical to CAMAPI.
Interface mapping
| CAMAPI interface | CAMIPC counterpart |
|---|---|
ICamApiProject |
ICamIpcProject |
ICamApiTechnologist |
ICamIpcTechnologist |
ICamApiTechOperation |
ICamIpcTechOperation |
ICamApiTechOperationIterator |
ICamIpcTechOperationIterator |
ICamApiTechOperationType |
ICamIpcTechOperationType |
ICamApiTechOperationTypeIterator |
ICamIpcTechOperationTypeIterator |
ICamApiPart |
ICamIpcPart |
ICamApiSetupStage |
ICamIpcSetupStage |
ICamApiPartStage |
ICamIpcPartStage |
ICamApiPartAndStageList |
ICamIpcPartAndStageList |
ICamApiSnapshot |
ICamIpcSnapshot |
IListCamApiSnapshot |
IListCamIpcSnapshot |
ICamApiUserTechOperationInfo |
ICamIpcUserTechOperationInfo |
ICamApiUserTechOperationList |
ICamIpcUserTechOperationList |
ICamIpcProject
Differences from ICamApiProject
All data-returning members are functions, not properties. In CAMAPI,
Id,FilePath, andTechnologistare COM properties. In CAMIPC they are explicitGetXxxfunctions, each takingTExecuteContext*.CAMAPI property CAMIPC function Id(property)GetId(ctx)FilePath(property)GetFilePath(ctx)Technologist(property)GetTechnologist(ctx)Snapshots(property)GetSnapshots(ctx)NCMaker(property)GetNCMaker(ctx)GeomImporter(property)GetGeomImporter(ctx)IsModified(property)GetIsModified(ctx)GetIsModifiedis a live check of the same condition that triggers the save prompt on close.ToolsList,CoordinateSystems,MachineInformation,Machine,Simulator,GeomModel,FeatureFinderremain as read-only properties (noctx) onICamIpcProject— they return IPC-variant types (ICamIpcMachiningToolsList,ICamIpcFeatureFinder, etc.).FeatureFinderis the new feature-recognition axis — seefeature-finder.md.SetMachine(guid, filePath, typeName, ctx)assigns a machine to the project.LoadMachineFromXmlProp(ctx)rebuilds the machine from its current XML properties — the apply step after editingMachine.XMLProp, for example flipping anActiveNodeselector to add or remove a turn table or a tail stock. Until it is called, the XML and the machine in memory disagree. UnlikeMachine.LoadFromOperationXml, which reloads the machine object alone, it also rebuilds everything derived from the machine: the initial machine state, the operation enability, the toolpath and the simulation. See../api/tools-machine.mdfor the walkthrough.SaveClDatatakesICamIpcTechOperationIterator*(the IPC variant) instead ofICamApiTechOperationIterator*.RegisterHandler/UnregisterHandleracceptICamIpcEventHandler*andICamIpcEventListener*(rather thanICamApiEventHandler*andIListString*).GetInstanceId()— every IPC object exposesGetInstanceId()(no ctx needed), which returns the stable IPC object identifier used internally for message routing. CAMAPI objects have no equivalent.
IPC-specific event handlers
Two save event handler interfaces exist in CAMIPC, mirroring CAMAPI:
ICamIpcHandlerProjectBeforeSave—ProjectBeforeSave(handlerIdent, project)ICamIpcHandlerProjectAfterSave—ProjectAfterSave(handlerIdent, project)
ICamIpcTechnologist
Differences from ICamApiTechnologist
All mutating and querying methods take
TExecuteContext*.CAMAPI CAMIPC GetActiveReorderingModeOfTechnology(out status)GetActiveReorderingModeOfTechnology(ctx)GetActiveReorderingModeOfSimulation(out status)GetActiveReorderingModeOfSimulation(ctx)GetOperations(mode, out status)GetOperations(mode, ctx)CalculateToolpath(links, out status)CalculateToolpath(links, ctx)CalculateAllOperationsToolpath(links, out status)CalculateAllOperationsToolpath(links, ctx)ResetToolpath()ResetToolpath(ctx)ResetAllOperationsToolpath()ResetAllOperationsToolpath(ctx)SwitchOperationEnability()SwitchOperationEnability(ctx)GetAvailableOperationTypeIds(out status)GetAvailableOperationTypeIds(ctx)CreateOperation(typeId, afterId, protoId, out status)CreateOperation(typeId, afterId, protoId, ctx)CreatePart(externalId, out status)CreatePart(externalId, ctx)CreateSetupStage(out status)CreateSetupStage(ctx)DeleteOperation(id, out status)DeleteOperation(id, ctx)DeletePart(partIdx, out status)DeletePart(partIdx, ctx)DeletePartStage(partIdx, stageIdx, incl, out status)DeletePartStage(partIdx, stageIdx, incl, ctx)DeleteSetupStage(stageIdx, out status)DeleteSetupStage(stageIdx, ctx)CreateOperationFromUserTemplate(userOpId, afterId, out status)CreateOperationFromUserTemplate(userOpId, afterId, ctx)GetOperationById(opId, out status)GetOperationById(opId, ctx)MoveOperation(opId, afterId, out status)MoveOperation(opId, afterId, ctx)CurrentOperationis read-only in CAMIPC (propertyR). To change the current operation use the separate procedure:SetCurrentOperation(operation, ctx)In CAMAPI,
CurrentOperationispropertyRWso it can be set directly.GetPartAndStageListis a function withctxin CAMIPC:GetPartAndStageList(ctx) → ICamIpcPartAndStageList*In CAMAPI it is a read-only property
PartAndStageList.OperationTypesremains a read-only property onICamIpcTechnologist(no ctx), returningICamIpcTechOperationTypeIterator*.OperationCatalogList— read-only property returningICamIpcOperationCatalogList*, the IPC mirror of the "New operation" window catalogs (see below).
Operation catalogs — ICamIpcOperationCatalogList
IPC mirror of the CAMAPI operation catalog tree (../api/project.md). The tree-walking and mutation methods take ctx; scalar properties do not:
ICamIpcOperationCatalogList—Count,Catalog[i];BeginUpdate(ctx)/EndUpdate(ctx)batch,CreateCatalog(name, ctx),DeleteCatalog(catalog, ctx),Import(zip, ctx),Export(catalog, zip, ctx).ICamIpcOperationCatalog—Id,Name(RW),IsActive(RW, set true to activate);GetItems(ctx),FindOperation(typeId, ctx),AddGroup(parent, index, caption, ctx),MoveItem(item, newParent, index, ctx),DeleteItem(item, ctx).ICamIpcOperationCatalogItem—Id,Kind(TCamApiOperationCatalogItemKind),Caption(RW),Visible(RW),Parent,Order; cast toICamIpcOperationCatalogGroup(IconFile) orICamIpcOperationCatalogOperation(TypeId,IsUserOperation) byKindviaAsInstanceOf.ICamIpcOperationCatalogItemIterator—Next,Current,Reset.
All add GetInstanceId().
IPC event handler
ICamIpcHandlerTechnologistOperationAdded — fires after a new operation is added:
OperationAdded(handlerIdent, operation: ICamIpcTechOperation*)
The CAMAPI equivalent is ICamApiHandlerTechnologistOperationAdded.
ICamIpcTechOperation
Differences from ICamApiTechOperation
All status-flag accessors are functions with
ctx(rather than properties):CAMAPI property CAMIPC function IdGetId(ctx)Name(RW)GetName(ctx)/SetName(name, ctx)EnabledGetEnabled(ctx)CalculatedGetCalculated(ctx)SimulatedGetSimulated(ctx)IsRapidErrorGetIsRapidError(ctx)IsHolderErrorGetIsHolderError(ctx)IsCompensationErrorGetIsCompensationError(ctx)IsPlungeErrorGetIsPlungeError(ctx)IsTravelErrorGetIsTravelError(ctx)IsCollisionErrorGetIsCollisionError(ctx)IsGougeErrorGetIsGougeError(ctx)IsToolOverloadErrorGetIsToolOverloadError(ctx)IsTurnDirectionErrorGetIsTurnDirectionError(ctx)IsMachiningResultCalculatedGetIsMachiningResultCalculated(ctx)IsErrorGetIsError(ctx)NeedDeleteChipsGetNeedDeleteChips(ctx)XMLPropreturnsICamIpcXmlPropPointer*instead ofIST_XMLPropPointer*. The property-accessor surface (Bol,Int,Flt,Str,Arr) is the same.LoadFromXmlProp/SaveToXmlPropaccept / returnICamIpcXmlPropPointer*and takectx:LoadFromXmlProp(xmlProp: ICamIpcXmlPropPointer*, ctx) SaveToXmlProp(ctx) → ICamIpcXmlPropPointer*ToolChangedevent handler (ICamIpcHandlerTechOperationToolChanged) gains an extra parameter compared to CAMAPI:ToolChanged(tool: ICamIpcMachiningTool*, justPropertyChange: boolean)justPropertyChange = truemeans only a property on the existing tool changed (the tool itself was not replaced). The CAMAPI handler does not have this parameter.Properties that remain as properties (no ctx):
XMLProp,Machine,WorkpieceCoordinateSystem,MachineConfiguration,ApproachRule(RW),ReturnRule(RW),ModelFormerJobAssignment,ModelFormerPart,ModelFormerWorkpiece,ModelFormerRestrictions,ModelFormerFixtures.Missing in CAMIPC vs CAMAPI:
OperationType(type-id string) — not exposed onICamIpcTechOperationIsGroupFullNameUnitsLCSPartIndex/SetupStageIndexTechnologist(back-reference)InitMachineEvaluatorGetPropIteratorOperationTag
These are available in-process only via
ICamApiTechOperation.
IPC event handlers on ICamIpcTechOperation
| Handler interface | Event | Difference from CAMAPI |
|---|---|---|
ICamIpcHandlerTechOperationInitModelFormers |
Model formers initialised | Parameter type is IUnknown* instead of ICamApiModelFormer* |
ICamIpcHandlerTechOperationLoadFromXmlProp |
Properties loaded from XML | Uses IST_XmlPropPointer* (same type name as CAMAPI) |
ICamIpcHandlerTechOperationSaveToXmlProp |
Properties saved to XML | Uses IST_XmlPropPointer* |
ICamIpcHandlerTechOperationToolChanged |
Tool changed | Extra justPropertyChange: boolean parameter |
ICamIpcHandlerTechOperationToolpathCalculated |
Body toolpath (re)computed | Receives only operation — no handlerIdent parameter, unlike the CAMAPI handler |
ToolpathCalculated fires only on a real body recompute — not for link/approach
recomputes, and not when a locked operation keeps its frozen toolpath.
Custom approach/return over IPC
The same structural editor as CAMAPI (../api/project.md),
but wired differently — worth reading even if you know the in-process API:
| CAMAPI | CAMIPC |
|---|---|
GetApproachRuleIsCustom(out rule) — one call returns the flag and a seeded rule |
GetApproachRule(ctx) and GetApproachIsCustom(ctx) — two separate calls |
SetApproachRuleIsCustom(rule) — takes the rule you built |
ApplyApproachRuleAsCustom(ctx) — no argument; persists the live list |
Over IPC the rule object is live over the operation: mutate its commands in place, then
call ApplyApproachRuleAsCustom / ApplyReturnRuleAsCustom to commit. There is nothing to
pass back, because the rule you edited is the operation's list.
rule := operation.GetApproachRule(ctx)
cmd := rule.AddCommand(0, ctx) // 0 = aprtGoto
cmd.SetAxisValue(2, 50.0, ctx) // Z = 50
cmd.SetAxisAuto(0, ctx) // X from the operation's final position
operation.ApplyApproachRuleAsCustom(ctx) // commit
ICamIpcApproachReturnRule: GetCommandCount, GetCommand(index),
AddCommand(positionType), DeleteCommand(index), Clear.
ICamIpcApproachReturnCommand: GetPositionType / SetPositionType, GetAxisCount, and
per-axis GetAxisId, GetAxisKind, GetAxisMode, GetAxisValue, SetAxisValue,
SetAxisAuto, SetAxisUnset.
Position type, axis mode and axis kind are plain
integerover IPC, not enums — pass and compare the ordinals ofTCamApiApproachReturnPositionType,TCamApiApproachReturnAxisModeandTCamApiApproachReturnAxisKind. The value tables are in../api/project.md.
SetPositionTyperebuilds the command's axis set, so set it before the axis values and re-readGetAxisCountafterwards.
ICamIpcTechOperationIterator
Differences from ICamApiTechOperationIterator
All navigation functions take ctx:
MoveToChild(ctx) → boolean
MoveToSibling(ctx) → boolean
MoveToParent(ctx) → boolean
Current(ctx) → ICamIpcTechOperation*
Reset(ctx)
There is no OperationsFilter property on ICamIpcTechOperationIterator (the filter
mechanism is CAMAPI-only).
ICamIpcSnapshot / IListCamIpcSnapshot
Differences from ICamApiSnapshot
Both accessors take ctx in the IPC variant:
| CAMAPI property | CAMIPC function |
|---|---|
CreationTime |
GetCreationTime(ctx) |
IsAuto |
GetIsAuto(ctx) |
IListCamIpcSnapshot has the same shape as IListCamApiSnapshot (Get, Count,
Add, Remove, RemoveAt) but returns ICamIpcSnapshot* items.
ICamIpcPart / ICamIpcSetupStage / ICamIpcPartStage / ICamIpcPartAndStageList
Differences from CAMAPI counterparts
All mutating methods on ICamIpcSetupStage take ctx:
SetToolConnector(toolId, connectorId, ctx)
ICamIpcPart, ICamIpcPartStage, and ICamIpcPartAndStageList expose the same
properties as their CAMAPI equivalents but gain GetInstanceId().
ICamIpcPart does not expose PrototypePartIndex or IsPartCopy (CAMAPI only).
ICamIpcPartAndStageList.GetPartStage has no ctx parameter (it is a lightweight
local look-up).
ICamIpcUserTechOperationInfo / ICamIpcUserTechOperationList
Differences from CAMAPI counterparts
ICamIpcUserTechOperationInfo.XMLProp returns ICamIpcXmlPropPointer* instead of
IST_XMLPropPointer*. It also adds the read-only BaseOperationTypeId property (same value as ICamIpcTechOperationType.Id), mirroring the CAMAPI addition.
Mutating list operations take ctx:
| CAMAPI | CAMIPC |
|---|---|
Remove(guid, out status) |
Remove(guid, ctx) |
AddFromFile(file, out status) |
AddFromFile(file, ctx) |
AddFromOp(caption, op, out status) |
AddFromOp(caption, op, ctx) |
Async vs sync
All CAMIPC methods are synchronous from the caller's perspective — the .NET helper
and the underlying IPC transport handle serialisation. The TExecuteContext may carry
a cancellation signal, but the call does not return until the remote side has completed
or faulted.
There is no callback-based async pattern in the current CAMIPC surface for the Project/Technologist domain.
Concise usage example
The code pattern for IPC is identical to CAMAPI at the helper level. The same
ComWrapper<T> idiom applies; just use the IPC-typed interfaces:
// Both lines look the same — the IPC context is managed inside ComWrapper
using var projectCom = applicationCom.GetActiveProject(); // ICamIpcProject
using var technologistCom = projectCom.InvokeAndWrap(p => p.GetTechnologist(ctx));
// Create an operation
using var opCom = technologistCom.InvokeAndWrap(tech =>
tech.CreateOperation("TSTWaterlineOp", afterOpId, "", ctx));
// Read a property (uses ctx internally)
string name = opCom.Invoke(op => op.GetName(ctx));
// Write XML properties (XMLProp property has no ctx; accessor calls do)
using var xmlPropCom = opCom.InvokeAndWrap(op => op.XMLProp);
xmlPropCom.Invoke(xp =>
{
xp.Bol["Roughing"] = true;
xp.Flt["RoughingStep"] = 10.0;
});
For complete working examples using CAMAPI (which share the same helper pattern), see: