/** * */ package org.goko.core.gcode.rs274ngcv3.modifier.array; import java.util.ArrayList; import java.util.List; import org.goko.core.common.exception.GkException; import org.goko.core.gcode.element.GCodeLine; import org.goko.core.gcode.element.IGCodeProvider; import org.goko.core.gcode.element.IInstructionSetIterator; import org.goko.core.gcode.rs274ngcv3.context.EnumDistanceMode; import org.goko.core.gcode.rs274ngcv3.context.GCodeContext; import org.goko.core.gcode.rs274ngcv3.element.GCodeProvider; import org.goko.core.gcode.rs274ngcv3.element.IModifier; import org.goko.core.gcode.rs274ngcv3.element.InstructionProvider; import org.goko.core.gcode.rs274ngcv3.element.InstructionType; import org.goko.core.gcode.rs274ngcv3.instruction.AbstractInstruction; import org.goko.core.gcode.rs274ngcv3.instruction.AbstractStraightInstruction; import org.goko.core.gcode.rs274ngcv3.instruction.ArcFeedInstruction; import org.goko.core.gcode.rs274ngcv3.modifier.AbstractModifier; import org.goko.core.math.Tuple6b; /** * Array modifier * * @author Psyko * @date 14 sept. 2016 */ public class ArrayModifier extends AbstractModifier<GCodeProvider> implements IModifier<GCodeProvider> { /** The offset between each copy */ private Tuple6b offset; /** The copy count */ private int count; /** * Constructor */ public ArrayModifier() { super("Array"); this.count = 1; this.offset = new Tuple6b().setZero(); } /** (inheritDoc) * @see org.goko.core.gcode.rs274ngcv3.element.IModifier#isConfigured() */ @Override public boolean isConfigured() { return offset != null; } /** (inheritDoc) * @see org.goko.core.gcode.rs274ngcv3.modifier.AbstractModifier#applyModifier(org.goko.core.gcode.element.IGCodeProvider, org.goko.core.gcode.rs274ngcv3.element.GCodeProvider) */ @Override protected void applyModifier(IGCodeProvider source, GCodeProvider target) throws GkException { GCodeContext localContext = new GCodeContext(); InstructionProvider sourceInstructionSet = getRS274NGCService().getInstructions(localContext, source); List<InstructionProvider> arrayInstructionSet = new ArrayList<InstructionProvider>(); List<Tuple6b> lstOffsets = new ArrayList<Tuple6b>(); // initialize the target instruction providers for (int i = 0; i < count; i++) { arrayInstructionSet.add(new InstructionProvider()); lstOffsets.add(offset.scale(1 + i)); } // Let's cache offset so they are not computed each time IInstructionSetIterator<GCodeContext, AbstractInstruction> iterator = getRS274NGCService().getIterator(sourceInstructionSet, localContext); while(iterator.hasNext()){ GCodeContext preContext = iterator.getContext(); AbstractInstruction instr = iterator.next(); for (int i = 0; i < count; i++) { AbstractInstruction clonedInstr = instr.clone(); // We only translate in relative distance if(preContext.getDistanceMode() == EnumDistanceMode.ABSOLUTE){ Tuple6b localOffset = lstOffsets.get(i); if(instr.getType() == InstructionType.STRAIGHT_FEED || instr.getType() == InstructionType.STRAIGHT_TRAVERSE){ translateStraightMotion((AbstractStraightInstruction) clonedInstr, localOffset, preContext); }else if(instr.getType() == InstructionType.ARC_FEED){ translateArcFeed((ArcFeedInstruction)clonedInstr, localOffset, preContext); } } arrayInstructionSet.get(i).addInstruction(clonedInstr); } } // Now let's merge the several providers for (int i = 0; i < count; i++) { sourceInstructionSet.addInstructionSet(arrayInstructionSet.get(i).getInstructionSets()); } GCodeProvider result = getRS274NGCService().getGCodeProvider(localContext, sourceInstructionSet); for (GCodeLine line : result.getLines()) { target.addLine(line); } } private void translateStraightMotion(AbstractStraightInstruction straightInstruction, Tuple6b offset, GCodeContext preContext) throws GkException { if(straightInstruction.getX() != null){ straightInstruction.setX(straightInstruction.getX().add(offset.getX())); } if(straightInstruction.getY() != null){ straightInstruction.setY(straightInstruction.getY().add(offset.getY())); } if(straightInstruction.getZ() != null){ straightInstruction.setZ(straightInstruction.getZ().add(offset.getZ())); } if(straightInstruction.getA() != null){ straightInstruction.setA(straightInstruction.getA().add(offset.getA())); } if(straightInstruction.getB() != null){ straightInstruction.setB(straightInstruction.getB().add(offset.getB())); } if(straightInstruction.getC() != null){ straightInstruction.setC(straightInstruction.getC().add(offset.getC())); } } /** * Translation of an arc feed instruction * @param instr the instruction * @param preContext the context in which the instruction is evaluated * @throws GkException GkException */ private void translateArcFeed(ArcFeedInstruction instr, Tuple6b offset, GCodeContext preContext) throws GkException { if(instr.getX() != null){ instr.setX(instr.getX().add(offset.getX())); } if(instr.getY() != null){ instr.setY(instr.getY().add(offset.getY())); } if(instr.getZ() != null){ instr.setZ(instr.getZ().add(offset.getZ())); } if(instr.getA() != null){ instr.setA(instr.getA().add(offset.getA())); } if(instr.getB() != null){ instr.setB(instr.getB().add(offset.getB())); } if(instr.getC() != null){ instr.setC(instr.getC().add(offset.getC())); } } /** * @return the offset */ public Tuple6b getOffset() { return offset; } /** * @param offset the offset to set */ public void setOffset(Tuple6b offset) { this.offset = offset; } /** * @return the count */ public int getCount() { return count; } /** * @param count the count to set */ public void setCount(int count) { this.count = count; } }