public void createCellLinks(double x, double y, Cell.LayerType layerType) { int coordX = (int)Math.Ceiling(x / cellNormalWidth) - 1; int coordY = (int)Math.Ceiling(y / cellNormalWidth) - 1; Cell c = findCellByCoords(coordX, coordY); if (c == null) c = createCell(coordX, coordY); c.setLayer(layerType); if (firstLinkingCell == null) { // premiere cellule : pas de lien firstLinkingCell = c; return; } else { if (c.x == firstLinkingCell.x && c.y == firstLinkingCell.y) { // toujours la même cellule : pas de lien return; } else { // cellule suivante : lien avec la cellule précédente bool lnkd = c.link(firstLinkingCell, layerType); if (lnkd) firstLinkingCell = c; else firstLinkingCell = null; } } }
public Cell clickCell(double x, double y, Cell.LayerType layerType) { int coordX = (int)Math.Ceiling(x / cellNormalWidth) - 1; int coordY = (int)Math.Ceiling(y / cellNormalWidth) - 1; Cell c = findCellByCoords(coordX, coordY); if (c == null) c = createCell(coordX, coordY); c.setLayer(layerType); draw(); return c; }
public CellLayer(Cell.LayerType layerType, Cell parentCell) { this.parentCell = parentCell; links = new Cell[Enum.GetValues(typeof(Cardinals)).Length]; this.layerType = layerType; }
public bool link(Cell originCell, LayerType layerType) { if (layers[(int)layerType].isSet && originCell.layers[(int)layerType].isSet) { // lien Nord if (originCell.x == x && originCell.y - y == -1) { layers[(int)layerType].links[(int)CellLayer.Cardinals.N] = originCell; originCell.layers[(int)layerType].links[(int)CellLayer.Cardinals.S] = this; originCell.draw(); return true; // lien Sud } else if (originCell.x == x && originCell.y - y == 1) { layers[(int)layerType].links[(int)CellLayer.Cardinals.S] = originCell; originCell.layers[(int)layerType].links[(int)CellLayer.Cardinals.N] = this; originCell.draw(); return true; // lien Ouest } else if (originCell.y == y && originCell.x - x == -1) { layers[(int)layerType].links[(int)CellLayer.Cardinals.W] = originCell; originCell.layers[(int)layerType].links[(int)CellLayer.Cardinals.E] = this; originCell.draw(); return true; // lien Est } else if (originCell.y == y && originCell.x - x == 1) { layers[(int)layerType].links[(int)CellLayer.Cardinals.E] = originCell; originCell.layers[(int)layerType].links[(int)CellLayer.Cardinals.W] = this; originCell.draw(); return true; } } // creation portes PNP NPN switch (layerType) { // PNP case LayerType.SILICON_N: if (layers[(int)LayerType.SILICON_P].isSet) { // nord if (originCell.x == x && originCell.y - y == -1) { if (layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.E] != null && layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.W] != null && layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.S] == null) { layers[(int)LayerType.PNP].isSet = true; layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.N] = originCell; layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.W] = circuit.findCellByCoords(x - 1, y); layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.E] = circuit.findCellByCoords(x + 1, y); originCell.layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.S] = this; layers[(int)LayerType.SILICON_N].isSet = false; layers[(int)LayerType.SILICON_P].isSet = false; draw(); originCell.draw(); } } else // sud if (originCell.x == x && originCell.y - y == 1) { if (layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.E] != null && layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.W] != null && layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.N] == null) { layers[(int)LayerType.PNP].isSet = true; layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.S] = originCell; layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.W] = circuit.findCellByCoords(x - 1, y); layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.E] = circuit.findCellByCoords(x + 1, y); originCell.layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.N] = this; layers[(int)LayerType.SILICON_N].isSet = false; layers[(int)LayerType.SILICON_P].isSet = false; draw(); originCell.draw(); } } else // ouest if (originCell.y == y && originCell.x - x == -1) { if (layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.N] != null && layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.S] != null && layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.E] == null) { layers[(int)LayerType.PNP].isSet = true; layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.W] = originCell; layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.S] = circuit.findCellByCoords(x, y + 1); layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.N] = circuit.findCellByCoords(x, y - 1); originCell.layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.E] = this; layers[(int)LayerType.SILICON_N].isSet = false; layers[(int)LayerType.SILICON_P].isSet = false; draw(); originCell.draw(); } } else // est if (originCell.y == y && originCell.x - x == 1) { if (layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.N] != null && layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.S] != null && layers[(int)LayerType.SILICON_P].links[(int)CellLayer.Cardinals.W] == null) { layers[(int)LayerType.PNP].isSet = true; layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.E] = originCell; layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.S] = circuit.findCellByCoords(x, y + 1); layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.N] = circuit.findCellByCoords(x, y - 1); originCell.layers[(int)LayerType.PNP].links[(int)CellLayer.Cardinals.W] = this; layers[(int)LayerType.SILICON_N].isSet = false; layers[(int)LayerType.SILICON_P].isSet = false; draw(); originCell.draw(); } } } break; // NPN case LayerType.SILICON_P: if (layers[(int)LayerType.SILICON_N].isSet) { // nord if (originCell.x == x && originCell.y - y == -1) { if (layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.E] != null && layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.W] != null && layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.S] == null) { layers[(int)LayerType.NPN].isSet = true; layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.N] = originCell; layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.W] = circuit.findCellByCoords(x - 1, y); layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.E] = circuit.findCellByCoords(x + 1, y); originCell.layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.S] = this; layers[(int)LayerType.SILICON_N].isSet = false; layers[(int)LayerType.SILICON_P].isSet = false; draw(); originCell.draw(); } } else // sud if (originCell.x == x && originCell.y - y == 1) { if (layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.E] != null && layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.W] != null && layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.N] == null) { layers[(int)LayerType.NPN].isSet = true; layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.S] = originCell; layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.W] = circuit.findCellByCoords(x - 1, y); layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.E] = circuit.findCellByCoords(x + 1, y); originCell.layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.N] = this; layers[(int)LayerType.SILICON_N].isSet = false; layers[(int)LayerType.SILICON_P].isSet = false; draw(); originCell.draw(); } } else // ouest if (originCell.y == y && originCell.x - x == -1) { if (layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.N] != null && layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.S] != null && layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.E] == null) { layers[(int)LayerType.NPN].isSet = true; layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.W] = originCell; layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.S] = circuit.findCellByCoords(x, y + 1); layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.N] = circuit.findCellByCoords(x, y - 1); originCell.layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.E] = this; layers[(int)LayerType.SILICON_N].isSet = false; layers[(int)LayerType.SILICON_P].isSet = false; draw(); originCell.draw(); } } else // est if (originCell.y == y && originCell.x - x == 1) { if (layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.N] != null && layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.S] != null && layers[(int)LayerType.SILICON_N].links[(int)CellLayer.Cardinals.W] == null) { layers[(int)LayerType.NPN].isSet = true; layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.E] = originCell; layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.S] = circuit.findCellByCoords(x, y + 1); layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.N] = circuit.findCellByCoords(x, y - 1); originCell.layers[(int)LayerType.NPN].links[(int)CellLayer.Cardinals.W] = this; layers[(int)LayerType.SILICON_N].isSet = false; layers[(int)LayerType.SILICON_P].isSet = false; draw(); originCell.draw(); } } } break; } return false; }
// cree une nouvelle cellule private Cell createCell(int x, int y) { Cell c = new Cell(x, y, this); cells.Add(c); updateStatusBarCellCount(); return c; }
public void stopLinking() { firstLinkingCell = null; }
public void deleteLayer(double x, double y, Cell.LayerType layerType) { int coordX = (int)Math.Ceiling(x / cellNormalWidth) - 1; int coordY = (int)Math.Ceiling(y / cellNormalWidth) - 1; Cell c = findCellByCoords(coordX, coordY); if (c != null) c.deleteLayer(layerType); // bool killCell = true; // foreach (CellLayer cl in c.layers) { // if (cl.isSet) { // killCell = false; // continue; // } // } // // if (killCell) { // cells.Remove(c); // updateStatusBarCellCount(); // } }
// cree récursivement les groupes de cellules en suivant les liens // FIXME : creer des liens dans l'éditeur pour trouver les portes // FIXME : ne pas grouper les layers silicon sous les portes !! private void groupAll(CellLayerGroup clg) { foreach (Cell c in clg.viaCells) { switch (clg.layers[0].layerType) { case Cell.LayerType.SILICON_N: if (c.layers[(int)Cell.LayerType.METAL].isSet && c.layers[(int)Cell.LayerType.METAL].groupedIn == false) { CellLayerGroup lg = createGroup(c.layers[(int)Cell.LayerType.METAL]); c.layerGroup = lg; LayerSubGroups.Add(lg); groupAll(lg); } break; case Cell.LayerType.SILICON_P: if (c.layers[(int)Cell.LayerType.METAL].isSet && c.layers[(int)Cell.LayerType.METAL].groupedIn == false) { CellLayerGroup lg = createGroup(c.layers[(int)Cell.LayerType.METAL]); c.layerGroup = lg; LayerSubGroups.Add(lg); groupAll(lg); } break; case Cell.LayerType.METAL: if (c.layers[(int)Cell.LayerType.SILICON_N].isSet && c.layers[(int)Cell.LayerType.SILICON_N].groupedIn == false) { CellLayerGroup lg = createGroup(c.layers[(int)Cell.LayerType.SILICON_N]); c.layerGroup = lg; LayerSubGroups.Add(lg); groupAll(lg); } if (c.layers[(int)Cell.LayerType.SILICON_P].isSet && c.layers[(int)Cell.LayerType.SILICON_P].groupedIn == false) { CellLayerGroup lg = createGroup(c.layers[(int)Cell.LayerType.SILICON_P]); c.layerGroup = lg; LayerSubGroups.Add(lg); groupAll(lg); } break; } } foreach (Cell c in subGates) { gates.Add(c); } Cell[] subGatesCopy = new Cell[subGates.Count]; subGates.CopyTo(subGatesCopy); subGates = new List<Cell>(); foreach (Cell c in subGatesCopy) { if (c.layers[(int)Cell.LayerType.NPN].isSet) { foreach (Cell lnkC in c.layers[(int)Cell.LayerType.NPN].links) { if (lnkC != null) { if (lnkC.layers[(int)Cell.LayerType.SILICON_N].isSet && lnkC.layers[(int)Cell.LayerType.SILICON_N].groupedIn == false ) { CellLayerGroup lg = createGroup(c.layers[(int)Cell.LayerType.SILICON_N]); LayerSubGroups.Add(lg); groupAll(lg); } else if (lnkC.layers[(int)Cell.LayerType.SILICON_P].isSet && lnkC.layers[(int)Cell.LayerType.SILICON_P].groupedIn == false ) { CellLayerGroup lg = createGroup(c.layers[(int)Cell.LayerType.SILICON_P]); LayerSubGroups.Add(lg); groupAll(lg); } } } } else if (c.layers[(int)Cell.LayerType.PNP].isSet) { foreach (Cell lnkC in c.layers[(int)Cell.LayerType.PNP].links) { // if (lnkC.layers[(int)Cell.LayerType.SILICON_N].isSet // && lnkC.layers[(int)Cell.LayerType.SILICON_N].groupedIn == false // ) { // // CellLayerGroup lg = createGroup(c.layers[(int)Cell.LayerType.SILICON_N]); // LayerSubGroups.Add(lg); // groupAll(lg); // // } else if (lnkC.layers[(int)Cell.LayerType.SILICON_P].isSet // && lnkC.layers[(int)Cell.LayerType.SILICON_P].groupedIn == false // ) { // // CellLayerGroup lg = createGroup(c.layers[(int)Cell.LayerType.SILICON_P]); // LayerSubGroups.Add(lg); // groupAll(lg); // // } } } } }