There's been numerous performance optimizations made to CmSym, which has caused a number of API-changes.
Because components on a sym node are limited, sequences are more efficient than maps both speed wise and storage wise. A number of breaking changes have been made so now we instead store components as a sequence field in SymNode
.
Instead of asking for:
featureProvider("mesh");
You use:
featureProvider(symFeature.mesh);
In this case it's simply better to use:
public SymComponent meshProvider(SymNode this) : inline {
This change is also made for performance reasons.
It's been very common for developers to simply add reps()
or reps3D()
to all their nodes. But it's undesirable to do so because it will implicitly create a LOD for all details, which have negative performance impacts.
Therefore you now have to explicitly ask for the exact details you want:
reps2D(#super) reps3D(#medium, #high)
This what the previous settings would produce:
reps2D() -> reps2D(#low, #medium, #high, #super) reps3D() -> reps3D(#low, #medium, #high, #super) reps() -> reps(#low, #medium, #high, #super)
(This also excludes the "base" detail level, but it should only exist in Model Lab so you should be able to ignore it).
Note that there's no support for any other 2D detail level than super.
A number of sym functions that were deprecated in 10.5 have been removed. This predominantly affects SymHandle
methods, such as:
myHandle.setMesh(newMesh);
Which can be replaced with:
symEdit(myHandle) { myHandle.xsetMesh(newMesh); }
or
SymHandle h = sym.beginEditHandle("path.to.handle"); h.xsetMaterial(greenGM); h.endEdit();
or
SymOwnerNode sym = sym(); sym.beginEdit("path.to.handle"); sym.handle("path.to.handle").xsetMesh(newMesh); sym.endEdit();
See the 10.0 to 10.5 migration guide for more information.
Do note that previously, handle.setMaterial()
used to be able to set the material for the entire model when loaded, but now each node on the model has its own material that blocks xsetMaterial()
from being able to set the material. Now it’s required to use xsetGroupMaterial()
to set the material for a handle of an imported sym file.
Instead of referring to components with string keys:
node.hasComponent("symReps"); node.getComponent("symReps"); node.removeComponent("symReps");
We now use identifiers:
node.hasComponent(symReps); node.getComponent(symReps); node.removeComponent(symReps);
All SymComponent
classes have their own entry in the symComponentId
:
public enum symComponentId { /** * An invalid component id, used for deprecated components. */ invalidSymComponent = 0; /** * All valid components. */ symGMaterial = 1; symGfx = 2; symMesh = 3; symProps = 4; symReps = 5; ...
Sometimes you'll get a name clash where symReps
can either refer to the enum or a method:
public void doStuff(SymNode this) { hasComponent(symReps); }
c:\CetDev\10.5git\base\cm\format\cmsym\component\test\test_components.cm(144, 26): no function hasComponent(SymReps (symReps(this, false)))
In which case you can explicitly refer to the enum entry like this:
public void doStuff(SymNode this) { hasComponent(symComponentId.symReps); }
This change was introduced for performance reasons.
If you were previously using:
prepareForEdit(h); h.doStuff();
to update components of a handle, it won't work now and you should use a symEdit
block instead.
Due to changes in sym validation we no longer construct a PathTrie
which points out the executed programs. Instead the executed programs are returned directly:
/** * Sym validation info. */ public class SymValidationInfo { /** * Rep. */ private SymRep rep : public readable; /** * Executed programs. */ private SymProgLazyExecEnv[] executedProgs : public readable;
public class SymProgLazyExecEnv { public SymExecEnv env; public SymProg prog; public SymProgs progs; public int depth; public int order; public constructor auto();
This was also made to minimize performance overhead.