[Bugfix] fixed Configuration getActive... routines

- getActiveStages() now correctly returns only active stages
- getActiveComponents() now returns children of all active stages exactly once
- Refactored the shape generate routines in rocketfigure
    - correctly omits inactive stages
    - always includes active stages
This commit is contained in:
Daniel_M_Williams 2015-09-20 17:55:18 -04:00
parent 497fb658c7
commit 34091e338e
2 changed files with 82 additions and 77 deletions

View File

@ -98,7 +98,7 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi
* @param stageNumber stage number to inactivate
*/
public void clearOnlyStage(final int stageNumber) {
setStage(stageNumber, false);
setStageActive(stageNumber, false);
}
/**
@ -107,7 +107,7 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi
* @param stageNumber stage number to activate
*/
public void setOnlyStage(final int stageNumber) {
setStage(stageNumber, true);
setStageActive(stageNumber, true);
}
/**
@ -116,9 +116,10 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi
* @param stageNumber stage number to flag
* @param _active inactive (<code>false</code>) or active (<code>true</code>)
*/
public void setStage(final int stageNumber, final boolean _active) {
public void setStageActive(final int stageNumber, final boolean _active) {
if ((0 <= stageNumber) && (stageMap.containsKey(stageNumber))) {
log.error("debug: setting stage " + stageNumber + " to " + _active);
String activeString = (_active ? "active" : "inactive");
log.error("debug: setting stage " + stageNumber + " to " + activeString + " " + this.toDebug());
stageMap.get(stageNumber).active = _active;
fireChangeEvent();
return;
@ -131,20 +132,21 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi
if ((0 <= stageNumber) && (stageMap.containsKey(stageNumber))) {
StageFlags flags = stageMap.get(stageNumber);
flags.active = !flags.active;
//log.error("debug: toggling stage " + stageNumber + " to " + !flags.active + " " + this.toDebug());
String activeString = (flags.active ? "active" : "inactive");
log.error("debug: toggling stage " + stageNumber + " to " + activeString + " " + this.toDebug());
fireChangeEvent();
return;
}
log.error("error: attempt to retrieve via a bad stage number: " + stageNumber);
}
/**
* Check whether the stage is active.
*/
public boolean isStageActive(final AxialStage stage) {
return this.isStageActive(stage.getStageNumber());
}
// /**
// * Check whether the stage is active.
// */
// public boolean isStageActive(final AxialStage stage) {
// return this.isStageActive(stage.getStageNumber());
// }
//
/**
* Check whether the stage specified by the index is active.
*/
@ -156,21 +158,19 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi
}
public Collection<RocketComponent> getActiveComponents() {
Queue<RocketComponent> toProcess = new ArrayDeque<RocketComponent>(this.rocket.getChildren());
Queue<RocketComponent> toProcess = new ArrayDeque<RocketComponent>(this.getActiveStages());
ArrayList<RocketComponent> toReturn = new ArrayList<RocketComponent>();
while (!toProcess.isEmpty()) {
RocketComponent comp = toProcess.poll();
if (comp instanceof AxialStage) {
if (!isStageActive(comp.getStageNumber())) {
continue;
}
}
toReturn.add(comp);
for (RocketComponent child : comp.getChildren()) {
toProcess.offer(child);
if (child instanceof AxialStage) {
continue;
} else {
toProcess.offer(child);
}
}
}
@ -196,7 +196,9 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi
List<AxialStage> activeStages = new ArrayList<AxialStage>();
for (StageFlags flags : this.stageMap.values()) {
activeStages.add(flags.stage);
if (flags.active) {
activeStages.add(flags.stage);
}
}
return activeStages;
@ -375,7 +377,6 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi
double minX = Double.POSITIVE_INFINITY, maxX = Double.NEGATIVE_INFINITY;
for (RocketComponent component : this.getActiveComponents()) {
System.err.println("..bounds checking component: " + component.getName());
for (Coordinate coord : component.getComponentBounds()) {
cachedBounds.add(coord);
if (coord.x < minX)

View File

@ -17,6 +17,7 @@ import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import net.sf.openrocket.gui.figureelements.FigureElement;
import net.sf.openrocket.gui.util.ColorConversion;
@ -25,6 +26,7 @@ import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorInstance;
import net.sf.openrocket.motor.MotorInstanceConfiguration;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.rocketcomponent.BoosterSet;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.Configuration;
import net.sf.openrocket.rocketcomponent.MotorMount;
@ -186,9 +188,7 @@ public class RocketFigure extends AbstractScaleFigure {
figureShapes.clear();
calculateSize();
Rocket theRocket = configuration.getRocket();
Coordinate zero = new Coordinate(0,0,0);
getShapeTree( figureShapes, theRocket, zero);
getShapes( figureShapes, configuration);
repaint();
fireChangeEvent();
@ -436,57 +436,46 @@ public class RocketFigure extends AbstractScaleFigure {
return l.toArray(new RocketComponent[0]);
}
// NOTE: Recursive function
private void getShapeTree(
ArrayList<RocketComponentShape> allShapes, // this is the output parameter
final RocketComponent comp,
final Coordinate parentLocation){
RocketPanel.VIEW_TYPE viewType = this.currentViewType;
Transformation viewTransform = this.transformation;
Coordinate componentAbsoluteLocation = parentLocation.add(comp.getOffset());
if( comp instanceof AxialStage){
int num = ((AxialStage) comp).getStageNumber();
if( ! this.configuration.isStageActive(num)){
return;
}
}
// generate shapes:
if( comp instanceof Rocket){
// no-op. no shapes
}else if( comp instanceof ComponentAssembly ){
// no-op; no shapes here, either.
}else{
// get all shapes for this component, add to return list.
RocketComponentShape[] childShapes = getThisShape( viewType, comp, componentAbsoluteLocation, viewTransform);
for ( RocketComponentShape curShape : childShapes ){
allShapes.add( curShape );
}
}
// recurse differently, depending on if this node has instances or not....
if( comp.isCenterline() ){
// recurse to each child with just the center
for( RocketComponent child: comp.getChildren() ){
getShapeTree( allShapes, child, componentAbsoluteLocation);
}
}else{
// get the offsets for each component instance
Coordinate[] instanceOffsets = new Coordinate[]{ parentLocation };
instanceOffsets = comp.shiftCoordinates( instanceOffsets);
// facade for the recursive function below
private void getShapes(ArrayList<RocketComponentShape> allShapes, Configuration configuration){
System.err.println("getting shapes for stages: " + this.configuration.toDebug());
for( AxialStage stage : configuration.getActiveStages()){
int stageNumber = stage.getStageNumber();
String activeString = ( configuration.isStageActive(stageNumber) ? "active" : "inactive");
System.err.println(" "+stage.getName()+ "[" + stageNumber + "] is " + activeString );
// recurse to each child with each instance of this component
for( RocketComponent child: comp.getChildren() ){
for( Coordinate curInstanceCoordinate : instanceOffsets){
getShapeTree( allShapes, child, curInstanceCoordinate);
}
}
getShapeTree( allShapes, stage, Coordinate.ZERO);
}
}
// NOTE: Recursive function
private void getShapeTree(
ArrayList<RocketComponentShape> allShapes, // this is the output parameter
final RocketComponent comp,
final Coordinate parentLocation){
RocketPanel.VIEW_TYPE viewType = this.currentViewType;
Transformation viewTransform = this.transformation;
Coordinate[] locs = comp.getLocation();
// generate shapes
for( Coordinate curLocation : locs){
allShapes = addThisShape( allShapes, viewType, comp, curLocation, viewTransform);
}
return;
// recurse into component's children
for( RocketComponent child: comp.getChildren() ){
if( child instanceof AxialStage ){
// recursing into BoosterSet here would double count its tree
continue;
}
for( Coordinate curLocation : locs){
getShapeTree( allShapes, child, curLocation);
}
}
return;
}
/**
@ -494,11 +483,21 @@ public class RocketFigure extends AbstractScaleFigure {
*
* @param component
* @param params
* @return
* @return the <code>ArrayList</code> containing all the shapes to draw.
*/
private static RocketComponentShape[] getThisShape(final RocketPanel.VIEW_TYPE viewType, final RocketComponent component, final Coordinate instanceOffset, final Transformation transformation) {
private static ArrayList<RocketComponentShape> addThisShape(
ArrayList<RocketComponentShape> allShapes, // this is the output parameter
final RocketPanel.VIEW_TYPE viewType,
final RocketComponent component,
final Coordinate instanceOffset,
final Transformation transformation) {
Reflection.Method m;
if(( component instanceof Rocket)||( component instanceof ComponentAssembly )){
// no-op; no shapes here, either.
return allShapes;
}
// Find the appropriate method
switch (viewType) {
case SideView:
@ -518,10 +517,15 @@ public class RocketFigure extends AbstractScaleFigure {
if (m == null) {
Application.getExceptionHandler().handleErrorCondition("ERROR: Rocket figure paint method not found for "
+ component);
return new RocketComponentShape[0];
return allShapes;
}
return (RocketComponentShape[]) m.invokeStatic(component, transformation, instanceOffset);
RocketComponentShape[] returnValue = (RocketComponentShape[]) m.invokeStatic(component, transformation, instanceOffset);
for ( RocketComponentShape curShape : returnValue ){
allShapes.add( curShape );
}
return allShapes;
}