Compile Time Changes

MhCantileverArmGfxBehavior interface changes

Old: extend public Primitive3D bracket3D(MhSnapper owner, double w, double startD, double endD, double startH, double h, double th) {
New: extend public Primitive3D bracket3D(MhSnapper owner, double w, double startD, double endD, double h, double th) {

Runtime/Behavior Changes

Abstract cantilever system populate changes

uprightDepth is now meant to be included in frameDepth by default, so we no longer manually add that value when retrieving the total frame depth.

Old:
public class MhCantileverSinglePopulator extends MhCantileverRowPopulator {
    public double cantileverFrameDepth() {
        double uprightD = uprightDepth;
        double frameD = frameDepth;
        return frameD uprightD;
    }
}


New:
public class MhCantileverSinglePopulator extends MhCantileverRowPopulator {
    public double cantileverFrameDepth() {
        return frameDepth;
    }
}


Old:
public class MhCantileverDoublePopulator extends MhCantileverRowPopulator {
    public double cantileverFrameDepth() {
        double uprightD = uprightDepth;
        double frameD = frameDepth;
        return frameD * 2 uprightD;
    }
}


New:
public class MhCantileverDoublePopulator extends MhCantileverRowPopulator {
    public double cantileverFrameDepth() {
        return frameDepth*2 - uprightDepth;
    }
}


Old:
public class MhCantileverRowPopulator extends MhStorageRowPopulator : abstract {
    extend public double cantileverBayDepth() {
        return frameDepth;
    }
}


New:
public class MhCantileverRowPopulator extends MhStorageRowPopulator : abstract {
    extend public double cantileverBayDepth() {
        return frameDepth - uprightDepth;
    }
}

The center bay has a new symbol added to it's classification sBayCenter.

Old:
    public MhEngineEntry createRackingRowEntry() {
        ...
        LayerSet centerBayLayer = layerSet(sBay, sFlueGap);
    }


New:
    public MhEngineEntry createRackingRowEntry() {
        ...
        LayerSet centerBayLayer = layerSet(sBay, sFlueGap, sBayCenter);
    }

Cantilever arm population on frames

Further changes have been made to construct and populate arm snappers on frame snappers.

public class MhCantileverLevelConstructionalPopulateFunction extends MhLevelConstructionalPopulateFunction {

    /**
     * Populator
     */
    public MhPopulator populator(box populateBox) {
        MhPopulator res = super(..);
        if (res as MhStepperPopulator) {
            point p = populateBox.p0;
            p.x += populateBox.w/2;
            res.startPos = p;
            res.currentPos = p;
        }

        return res;
    }


    /**
     * Execute.
     */
    public Object exec() {
        ?MhStorageConfiguration config = configuration();
        if (!config) return false;

        if (isFrame(parent)) {
            double uprightD = config.frameUprightDepth().safeDouble();
            if (isDouble(parent)) { // Populate arms front and back.
                MhEngineConstructionEntry[] children;
                str key = parent.cacheKey();
                ?children = mhSystemEngineCache.get(key).?obj.copy();

                if (children.empty) {
                    box b = parent.localBound;
                    b.d = (b.d - uprightD)/2;
                    box b1 = b.moved((b.p0.x, b.p1.y uprightD, b.p0.z));
                    MhEngineConstructionEntry[] front = populateLevels(0, b);
                    MhEngineConstructionEntry[] back = populateLevels(0, b1, 0deg);
                    children = front back;
                    mhSystemEngineCache.put(key, children.copy());
                }

                for (c in children) parent << c;

                return true;
            }

            // Single frame.
            box b = parent.localBound();
            b.d = b.d - uprightD;
            addLevels(0, b);
            return true;
        }

        return super(..);
    }


    /**
     * EntryLayout.
     * Why call it a bayEntry when it can be any entry?
     */
    public MhBayEntryLayout entryLayout() {
        if (MhSystemSpawnerSelector ss = getSpawnerSelector) {
            ?MhSnapperSpawner frame = getSpawnerSelector.?spawner(layerSet(sFrame));
            return frame.?entryLayout(ss).?MhBayEntryLayout;
        }

        return null;
    }


    /**
     * Default entry.
     */
    public MhEngineConstructionEntry defaultLevelEntry(box b, LayerSet classification) {
        if (isFrame(parent)) return super(..);
        return null;
    }
public class MhCantileverFrameEngineBehavior extends MhFrameEngineBehavior {

    /**
     * Put engine function to run.
     */
    public void putEngineRunFunctions(MhSnapper snapper, symbol event="", Object env=null) {
        if (!snapper) return;
        MhEngine engine = engine(snapper);
        switch(event) {
          case sShapeChange, sShapeAndSymChange : {
              if (env as MhSnapperChangedEnv) {
                  bool stealing = false;

                  if (snapper != env.owner) {
                      if (MhSnapper stealSource = getStealSource(env, snapper)) {
                          stealing = true;
                          mhPutEngineRunFunction(engine, "rowChildStealConfig", snapper=snapper, source=stealSource);
                      }
                  }

                  Object holeZDomain = snapper.domain("holeZDomain");
                  CollisionPrimitive additionalPrim = additionalPrim(snapper);
                  if (env.translatedKey in ["uprightH", "h"] and !stealing) {
                      if (levelPopulate(snapper)) {
                          // level height changed
                          mhPutEngineRunFunction(engine, "levelPopulate", snapper=snapper,
                                                 holeZDomain=holeZDomain,
                                                 loadWithinLimit=loadWithinLimit(snapper),
                                                 revertAutoULPopulate=revertAutoULPopulate(snapper),
                                                 additionalPrim=additionalPrim,
                                                 configKey=snapper.configName);
                      }
                  }
                  if (env.translatedKey in ["d", "h"] and !stealing) {
                      // Run level arrange, since cantilever levels are children to frames.
                      mhPutEngineRunFunction(engine, "levelArrange", snapper=snapper,
                                             holeZDomain=holeZDomain,
                                             additionalPrim=additionalPrim);
                  }
              }
          }
          case sSnapperInserted: {
              Object holeZDomain = snapper.domain("holeZDomain");
              CollisionPrimitive additionalPrim = additionalPrim(snapper);

              // Run level arrange, since cantilever levels are children to frames.
              mhPutEngineRunFunction(engine, "levelArrange", snapper=snapper,
                                     holeZDomain=holeZDomain,
                                     additionalPrim=additionalPrim);

          }
          default : {
          }
        };
        super(..);
    }


    /**
     * Collect engine function to run.
     */
    public void fetchEngineFunctionsRunG2(MhEngineFunctionRun[] functions, MhSnapper snapper, symbol event="", Object env=null) {
        super(..);
        switch (event) {
          case sShapeChange, sShapeAndSymChange : {
              functions << MhEngineFunctionRun("rowChildStealConfig");
              functions << MhEngineFunctionRun("levelPopulate");
              functions << MhEngineFunctionRun("levelArrange");
          }
          case sSnapperInserted: {
              functions << MhEngineFunctionRun("levelArrange");
          }
          default :;
        };
    }


    /**
     * Gather function args.
     */
    public str->Object engineFunctionArgsG2(MhSnapper snapper, MhEngineFunctionRun func, symbol event="",
                                                   MhPreprocessArgsEnv preprocessArgs=null, Object env=null) {
        switch (func.name) {
          case "levelPopulate" : {
              return props { snapper=snapper,
                    holeZDomain=snapper.domain("holeZDomain"),
                    loadWithinLimit=loadWithinLimit(snapper),
                    revertAutoULPopulate=revertAutoULPopulate(snapper),
                    additionalPrim=additionalPrim(snapper),
                    configKey=snapper.configName };
          }

          case "levelArrange" : {
              return props { snapper=snapper,
                    holeZDomain=snapper.domain("holeZDomain"),
                    additionalPrim=additionalPrim(snapper) };
          }

          default :;
        };


        return super(..);
    }


    /**
     * Accepts function run.
     */
    public bool acceptFunctionRunG2(MhSnapper snapper, MhEngineFunctionRun func, symbol event="", Object env=null) {
        switch (func.name) {
          case "levelPopulate" : {
              if (env as MhSnapperChangedEnv) {
                  if (snapper != env.owner) {
                      if (MhSnapper stealSource = getStealSource(env, snapper)) {
                          return false;
                      }
                  }

                  return env.translatedKey in ["uprightH", "h"] and levelPopulate(snapper);
              }
              return false;
          }
          case "levelArrange" : {
              if (event in [sShapeChange, sShapeAndSymChange]) {
                  if (env as MhSnapperChangedEnv) {
                      if (snapper != env.owner) {
                          if (MhSnapper stealSource = getStealSource(env, snapper)) {
                              return false;
                          }
                      }
                      return env.translatedKey in ["d", "h"];
                  }
                  return false;
              } else if (event == sSnapperInserted) {
                  return true;
              }
          }
          default :;
        };
        return super(..);
    }


    /**
     * Invalidate and return true if required.
     */
    public bool invalidateIfRequired(Object owner, symbol k, MhSnapperChangedEnv env=null) {
        if (k == sAfterInitialExport) return true;
        return super(..);
    }