Merge branch 'unstable' into issue-1351
This commit is contained in:
commit
b0754e3e8a
Binary file not shown.
@ -299,7 +299,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
// warnings.add(Warning.DISCONTINUITY);
|
||||
// radius = 0;
|
||||
//}
|
||||
//componentX = component.toAbsolute(new Coordinate(component.getLength()))[0].x;
|
||||
//componentX = component.toAbsolute(new Coordinate(component.getLengthAerodynamic()))[0].x;
|
||||
|
||||
prevComp = sym;
|
||||
}else if( comp instanceof ComponentAssembly ){
|
||||
@ -364,7 +364,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
Finish finish = ((ExternalComponent) c).getFinish();
|
||||
if (Double.isNaN(roughnessLimited[finish.ordinal()])) {
|
||||
roughnessLimited[finish.ordinal()] =
|
||||
0.032 * Math.pow(finish.getRoughnessSize() / configuration.getLength(), 0.2) *
|
||||
0.032 * Math.pow(finish.getRoughnessSize() / configuration.getLengthAerodynamic(), 0.2) *
|
||||
roughnessCorrection;
|
||||
}
|
||||
|
||||
@ -442,7 +442,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
* @return Reynolds Number
|
||||
*/
|
||||
private double calculateReynoldsNumber(FlightConfiguration configuration, FlightConditions conditions) {
|
||||
return conditions.getVelocity() * configuration.getLength() /
|
||||
return conditions.getVelocity() * configuration.getLengthAerodynamic() /
|
||||
conditions.getAtmosphericConditions().getKinematicViscosity();
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ public class FinSetCalc extends RocketComponentCalc {
|
||||
// forces.CrollForce = fins * (macSpan+r) * cna1 * component.getCantAngle() /
|
||||
// conditions.getRefLength();
|
||||
// With body-fin interference effect:
|
||||
forces.setCrollForce(finCount * (macSpan + r) * cna1 * (1 + tau) * cantAngle / conditions.getRefLength());
|
||||
forces.setCrollForce((macSpan + r) * cna1 * (1 + tau) * cantAngle / conditions.getRefLength());
|
||||
|
||||
if (conditions.getAOA() > STALL_ANGLE) {
|
||||
// System.out.println("Fin stalling in roll");
|
||||
@ -481,17 +481,17 @@ public class FinSetCalc extends RocketComponentCalc {
|
||||
(conditions.getRefArea() * conditions.getRefLength());
|
||||
|
||||
// System.out.println("SPECIAL: " +
|
||||
// (MathUtil.sign(rollRate) *component.getFinCount() * sum));
|
||||
return MathUtil.sign(rollRate) * finCount * sum;
|
||||
// (MathUtil.sign(rollRate) * sum));
|
||||
return MathUtil.sign(rollRate) * sum;
|
||||
}
|
||||
|
||||
if (mach <= CNA_SUBSONIC) {
|
||||
// System.out.println("BASIC: "+
|
||||
// (component.getFinCount() * 2*Math.PI * rollRate * rollSum /
|
||||
// (2*Math.PI * rollRate * rollSum /
|
||||
// (conditions.getRefArea() * conditions.getRefLength() *
|
||||
// conditions.getVelocity() * conditions.getBeta())));
|
||||
|
||||
return finCount * 2 * Math.PI * rollRate * rollSum /
|
||||
return 2 * Math.PI * rollRate * rollSum /
|
||||
(conditions.getRefArea() * conditions.getRefLength() *
|
||||
conditions.getVelocity() * conditions.getBeta());
|
||||
}
|
||||
@ -512,7 +512,7 @@ public class FinSetCalc extends RocketComponentCalc {
|
||||
* chordLength[i] * (bodyRadius + y);
|
||||
}
|
||||
|
||||
return finCount * sum * span / (DIVISIONS - 1) /
|
||||
return sum * span / (DIVISIONS - 1) /
|
||||
(conditions.getRefArea() * conditions.getRefLength());
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
|
||||
// Stage refStage = (Stage) this.parent;
|
||||
// System.err.println(" >>refStageName: " + refStage.getName() + "\n");
|
||||
// System.err.println(" ..refCenterX: " + refStage.position.x + "\n");
|
||||
// System.err.println(" ..refLength: " + refStage.getLength() + "\n");
|
||||
// System.err.println(" ..refLength: " + refStage.getLengthAerodynamic() + "\n");
|
||||
// }
|
||||
return buf;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -67,8 +66,10 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
final private InstanceMap activeInstances = new InstanceMap();
|
||||
|
||||
private int boundsModID = -1;
|
||||
private BoundingBox cachedBounds = new BoundingBox();
|
||||
private double cachedLength = -1;
|
||||
private BoundingBox cachedBoundsAerodynamic = new BoundingBox(); // Bounding box of all aerodynamic components
|
||||
private BoundingBox cachedBounds = new BoundingBox(); // Bounding box of all components
|
||||
private double cachedLengthAerodynamic = -1; // Rocket length of all aerodynamic components
|
||||
private double cachedLength = -1; // Rocket length of all components
|
||||
|
||||
private int refLengthModID = -1;
|
||||
private double cachedRefLength = -1;
|
||||
@ -566,15 +567,31 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
*
|
||||
* @return a <code>Collection</code> containing coordinates bounding the rocket.
|
||||
*
|
||||
* @deprecated Migrate to <FlightConfiguration>.getBoundingBox(), when practical.
|
||||
* @deprecated Migrate to <FlightConfiguration>.getBoundingBoxAerodynamic(), when practical.
|
||||
*/
|
||||
@Deprecated
|
||||
public Collection<Coordinate> getBounds() {
|
||||
return getBoundingBox().toCollection();
|
||||
return getBoundingBoxAerodynamic().toCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bounding box of the current configuration.
|
||||
* Return the bounding box of the current configuration (of aerodynamic components).
|
||||
*
|
||||
* @return the rocket's bounding box (under the selected configuration)
|
||||
*/
|
||||
public BoundingBox getBoundingBoxAerodynamic() {
|
||||
// if (rocket.getModID() != boundsModID) {
|
||||
calculateBounds();
|
||||
// }
|
||||
|
||||
if(cachedBoundsAerodynamic.isEmpty())
|
||||
cachedBoundsAerodynamic = new BoundingBox(Coordinate.ZERO,Coordinate.X_UNIT);
|
||||
|
||||
return cachedBoundsAerodynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bounding box of the current configuration (of all components).
|
||||
*
|
||||
* @return the rocket's bounding box (under the selected configuration)
|
||||
*/
|
||||
@ -594,20 +611,16 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
* in the current configuration.
|
||||
*/
|
||||
private void calculateBounds() {
|
||||
BoundingBox rocketBounds = new BoundingBox();
|
||||
BoundingBox rocketBoundsAerodynamic = new BoundingBox(); // Bounding box of all aerodynamic components
|
||||
BoundingBox rocketBounds = new BoundingBox(); // Bounding box of all components
|
||||
|
||||
InstanceMap map = getActiveInstances();
|
||||
for (Map.Entry<RocketComponent, java.util.ArrayList<InstanceContext>> entry : map.entrySet()) {
|
||||
final RocketComponent component = entry.getKey();
|
||||
final BoundingBox componentBoundsAerodynamic = new BoundingBox();
|
||||
final BoundingBox componentBounds = new BoundingBox();
|
||||
final List<InstanceContext> contexts = entry.getValue();
|
||||
|
||||
if( ! component.isAerodynamic()){
|
||||
// System.err.println(" << non-aerodynamic");
|
||||
// all non-aerodynamic components should be surrounded by aerodynamic ones
|
||||
continue;
|
||||
}
|
||||
|
||||
// FinSets already provide a bounding box, so let's use that.
|
||||
if (component instanceof BoxBounded) {
|
||||
final BoundingBox instanceBounds = ((BoxBounded) component).getInstanceBoundingBox();
|
||||
@ -618,6 +631,9 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
}
|
||||
|
||||
for (InstanceContext context : contexts) {
|
||||
if (component.isAerodynamic()) {
|
||||
componentBoundsAerodynamic.update(instanceBounds.transform(context.transform));
|
||||
}
|
||||
componentBounds.update(instanceBounds.transform(context.transform));
|
||||
}
|
||||
} else {
|
||||
@ -629,28 +645,50 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
context.transform.transform(instanceCoordinates);
|
||||
|
||||
for (Coordinate tc : transformedCoords) {
|
||||
if (component.isAerodynamic()) {
|
||||
componentBoundsAerodynamic.update(tc);
|
||||
}
|
||||
componentBounds.update(tc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rocketBoundsAerodynamic.update(componentBoundsAerodynamic);
|
||||
rocketBounds.update(componentBounds);
|
||||
}
|
||||
|
||||
boundsModID = rocket.getModID();
|
||||
cachedLengthAerodynamic = rocketBoundsAerodynamic.span().x;
|
||||
cachedLength = rocketBounds.span().x;
|
||||
/* Special case for the scenario that all of the stages are removed and are
|
||||
* inactive. Its possible that this shouldn't be allowed, but it is currently
|
||||
* so we'll just adjust the length here.
|
||||
*/
|
||||
if (rocketBoundsAerodynamic.isEmpty()) {
|
||||
cachedLengthAerodynamic = 0;
|
||||
}
|
||||
if (rocketBounds.isEmpty()) {
|
||||
cachedLength = 0;
|
||||
}
|
||||
cachedBoundsAerodynamic = rocketBoundsAerodynamic;
|
||||
cachedBounds = rocketBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the rocket configuration, from the foremost bound X-coordinate
|
||||
* Returns the length of the rocket configuration (only aerodynamic components), from the foremost bound X-coordinate
|
||||
* to the aft-most X-coordinate. The value is cached.
|
||||
*
|
||||
* @return the length of the rocket in the X-direction.
|
||||
*/
|
||||
public double getLengthAerodynamic() {
|
||||
if (rocket.getModID() != boundsModID) {
|
||||
calculateBounds();
|
||||
}
|
||||
return cachedLengthAerodynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the rocket configuration (all components), from the foremost bound X-coordinate
|
||||
* to the aft-most X-coordinate. The value is cached.
|
||||
*
|
||||
* @return the length of the rocket in the X-direction.
|
||||
@ -678,6 +716,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
FlightConfiguration clone = new FlightConfiguration( this.rocket, this.fcid );
|
||||
clone.setName(configurationName);
|
||||
|
||||
clone.cachedBoundsAerodynamic = this.cachedBoundsAerodynamic.clone();
|
||||
clone.cachedBounds = this.cachedBounds.clone();
|
||||
clone.modID = this.modID;
|
||||
clone.boundsModID = -1;
|
||||
@ -705,6 +744,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
cloneMotor.getMount().setMotorConfig(cloneMotor, copyId);
|
||||
}
|
||||
|
||||
copy.cachedBoundsAerodynamic = this.cachedBoundsAerodynamic.clone();
|
||||
copy.cachedBounds = this.cachedBounds.clone();
|
||||
copy.modID = this.modID;
|
||||
copy.boundsModID = -1;
|
||||
|
@ -189,7 +189,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable {
|
||||
// Stage refStage = (Stage) this.parent;
|
||||
// System.err.println(" >>refStageName: " + refStage.getName() + "\n");
|
||||
// System.err.println(" ..refCenterX: " + refStage.position.x + "\n");
|
||||
// System.err.println(" ..refLength: " + refStage.getLength() + "\n");
|
||||
// System.err.println(" ..refLength: " + refStage.getLengthAerodynamic() + "\n");
|
||||
// }
|
||||
return buf;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ public interface RadialParent {
|
||||
|
||||
/**
|
||||
* Return the outer radius of the component at local coordinate <code>x</code>.
|
||||
* Values for <code>x < 0</code> and <code>x > getLength()</code> are undefined.
|
||||
* Values for <code>x < 0</code> and <code>x > getLengthAerodynamic()</code> are undefined.
|
||||
*
|
||||
* @param x the lengthwise position in the coordinates of this component.
|
||||
* @return the outer radius of the component at that position.
|
||||
@ -13,7 +13,7 @@ public interface RadialParent {
|
||||
|
||||
/**
|
||||
* Return the inner radius of the component at local coordinate <code>x</code>.
|
||||
* Values for <code>x < 0</code> and <code>x > getLength()</code> are undefined.
|
||||
* Values for <code>x < 0</code> and <code>x > getLengthAerodynamic()</code> are undefined.
|
||||
*
|
||||
* @param x the lengthwise position in the coordinates of this component.
|
||||
* @return the inner radius of the component at that position.
|
||||
|
@ -395,7 +395,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
|
||||
@Override
|
||||
public double getLongitudinalUnitInertia() {
|
||||
// 1/12 * (3 * (r2^2 + r1^2) + h^2)
|
||||
// return (3 * (MathUtil.pow2(getOuterRadius()) + MathUtil.pow2(getInnerRadius())) + MathUtil.pow2(getLength())) / 12;
|
||||
// return (3 * (MathUtil.pow2(getOuterRadius()) + MathUtil.pow2(getInnerRadius())) + MathUtil.pow2(getLengthAerodynamic())) / 12;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ public class Rocket extends ComponentAssembly {
|
||||
*
|
||||
* @return Return a bounding box enveloping the rocket
|
||||
*/
|
||||
public BoundingBox getBoundingBox (){ return selectedConfiguration.getBoundingBox(); }
|
||||
public BoundingBox getBoundingBox (){ return selectedConfiguration.getBoundingBoxAerodynamic(); }
|
||||
|
||||
public String getDesigner() {
|
||||
checkState();
|
||||
|
@ -138,7 +138,7 @@ public class BasicLandingStepper extends AbstractSimulationStepper {
|
||||
data.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, linearAcceleration.length());
|
||||
|
||||
double Re = airSpeed.length() *
|
||||
status.getConfiguration().getLength() /
|
||||
status.getConfiguration().getLengthAerodynamic() /
|
||||
atmosphere.getKinematicViscosity();
|
||||
data.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Re);
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ public class BasicTumbleStepper extends AbstractSimulationStepper {
|
||||
data.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, linearAcceleration.length());
|
||||
|
||||
double Re = airSpeed.length() *
|
||||
status.getConfiguration().getLength() /
|
||||
status.getConfiguration().getLengthAerodynamic() /
|
||||
atmosphere.getKinematicViscosity();
|
||||
data.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Re);
|
||||
}
|
||||
|
@ -582,7 +582,7 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
|
||||
if (store.flightConditions != null) {
|
||||
double Re = (store.flightConditions.getVelocity() *
|
||||
status.getConfiguration().getLength() /
|
||||
status.getConfiguration().getLengthAerodynamic() /
|
||||
store.flightConditions.getAtmosphericConditions().getKinematicViscosity());
|
||||
data.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Re);
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ public class PercentageOfLengthUnit extends GeneralUnit {
|
||||
* @return the reference length of the rocket
|
||||
*/
|
||||
public static double getReferenceLength(FlightConfiguration config) {
|
||||
return config.getLength();
|
||||
return config.getLengthAerodynamic();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,18 +1,12 @@
|
||||
package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.position.AngleMethod;
|
||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
||||
import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
||||
import net.sf.openrocket.util.BoundingBox;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.TestRockets;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@ -25,7 +19,7 @@ public class BoundingBoxTest extends BaseTestCase {
|
||||
final Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
|
||||
final FlightConfiguration config = rocket.getSelectedConfiguration();
|
||||
final BoundingBox bounds = config.getBoundingBox();
|
||||
final BoundingBox bounds = config.getBoundingBoxAerodynamic();
|
||||
|
||||
assertEquals("bounds max x", 0.000000000, bounds.min.x, EPSILON);
|
||||
assertEquals("bounds max x", 0.270000000, bounds.max.x, EPSILON);
|
||||
@ -48,7 +42,7 @@ public class BoundingBoxTest extends BaseTestCase {
|
||||
// DEBUG
|
||||
System.err.println("==== Case A: All Stages ====");
|
||||
|
||||
final BoundingBox bounds = config.getBoundingBox();
|
||||
final BoundingBox bounds = config.getBoundingBoxAerodynamic();
|
||||
|
||||
assertEquals("bounds min x", 0.000000000, bounds.min.x, EPSILON);
|
||||
assertEquals("bounds max x", 0.335000000, bounds.max.x, EPSILON);
|
||||
@ -63,7 +57,7 @@ public class BoundingBoxTest extends BaseTestCase {
|
||||
// DEBUG
|
||||
System.err.println("==== Case B: Sustainer Only ====");
|
||||
|
||||
final BoundingBox bounds = config.getBoundingBox();
|
||||
final BoundingBox bounds = config.getBoundingBoxAerodynamic();
|
||||
|
||||
assertEquals("bounds min x", 0.000000000, bounds.min.x, EPSILON);
|
||||
assertEquals("bounds max x", 0.270000000, bounds.max.x, EPSILON);
|
||||
@ -79,7 +73,7 @@ public class BoundingBoxTest extends BaseTestCase {
|
||||
System.err.println("==== Case C: Booster Only ====");
|
||||
System.err.println(rocket.toDebugTree());
|
||||
|
||||
final BoundingBox bounds = config.getBoundingBox();
|
||||
final BoundingBox bounds = config.getBoundingBoxAerodynamic();
|
||||
|
||||
assertEquals("bounds min x", 0.270000000, bounds.min.x, EPSILON);
|
||||
assertEquals("bounds max x", 0.335000000, bounds.max.x, EPSILON);
|
||||
|
@ -45,7 +45,7 @@ public class FlightConfigurationTest extends BaseTestCase {
|
||||
assertThat("active stage count doesn't match", config.getActiveStageCount(), equalTo(2));
|
||||
|
||||
final double expectedLength = 0.335;
|
||||
final double calculatedLength = config.getLength();
|
||||
final double calculatedLength = config.getLengthAerodynamic();
|
||||
assertEquals("source config length doesn't match: ", expectedLength, calculatedLength, EPSILON);
|
||||
|
||||
double expectedReferenceLength = 0.024;
|
||||
@ -71,7 +71,7 @@ public class FlightConfigurationTest extends BaseTestCase {
|
||||
int actualMotorCount = config1.getActiveMotors().size();
|
||||
assertThat("active motor count doesn't match", actualMotorCount, equalTo(expectedMotorCount));
|
||||
double expectedLength = 0.335;
|
||||
assertEquals("source config length doesn't match: ", expectedLength, config1.getLength(), EPSILON);
|
||||
assertEquals("source config length doesn't match: ", expectedLength, config1.getLengthAerodynamic(), EPSILON);
|
||||
double expectedReferenceLength = 0.024;
|
||||
assertEquals("source config reference length doesn't match: ", expectedReferenceLength, config1.getReferenceLength(), EPSILON);
|
||||
double expectedReferenceArea = Math.pow(expectedReferenceLength/2,2)*Math.PI;
|
||||
@ -90,7 +90,7 @@ public class FlightConfigurationTest extends BaseTestCase {
|
||||
expectedMotorCount = 2;
|
||||
actualMotorCount = config2.getActiveMotors().size();
|
||||
assertThat("active motor count doesn't match", actualMotorCount, equalTo(expectedMotorCount));
|
||||
assertEquals("source config length doesn't match: ", expectedLength, config2.getLength(), EPSILON);
|
||||
assertEquals("source config length doesn't match: ", expectedLength, config2.getLengthAerodynamic(), EPSILON);
|
||||
assertEquals("source config reference length doesn't match: ", expectedReferenceLength, config2.getReferenceLength(), EPSILON);
|
||||
assertEquals("source config reference area doesn't match: ", expectedReferenceArea, config2.getReferenceArea(), EPSILON);
|
||||
|
||||
|
@ -203,7 +203,7 @@ public class ComponentRenderer {
|
||||
if (t.getForeShoulderLength() > 0) {
|
||||
gl.glPushMatrix();
|
||||
gl.glRotated(180, 0, 1.0, 0);
|
||||
//gl.glTranslated(t.getLength(), 0, 0);
|
||||
//gl.glTranslated(t.getLengthAerodynamic(), 0, 0);
|
||||
double iR = (t.isFilled() || t.isForeShoulderCapped()) ? 0 : t.getForeShoulderRadius() - t.getForeShoulderThickness();
|
||||
if (which == Surface.EDGES) {
|
||||
renderTube(gl, Surface.OUTSIDE, t.getForeShoulderRadius(), iR, t.getForeShoulderLength());
|
||||
|
@ -33,7 +33,6 @@ import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
|
||||
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
|
||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||
import net.sf.openrocket.arch.SystemInfo;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.document.events.SimulationChangeEvent;
|
||||
@ -63,10 +62,8 @@ import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||
import net.sf.openrocket.simulation.FlightData;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.customexpression.CustomExpression;
|
||||
import net.sf.openrocket.simulation.customexpression.CustomExpressionSimulationListener;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.simulation.listeners.SimulationListener;
|
||||
import net.sf.openrocket.simulation.listeners.system.GroundHitListener;
|
||||
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
|
||||
@ -599,6 +596,8 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
List<RocketComponent> selectedComponents = Arrays.stream(selectionModel.getSelectionPaths())
|
||||
.map(c -> (RocketComponent) c.getLastPathComponent()).collect(Collectors.toList());
|
||||
|
||||
if (clicked == null || clicked.length == 0) return;
|
||||
|
||||
// If the shift-button is held, add a newly clicked component to the selection path
|
||||
if ((event.isShiftDown() || event.isMetaDown()) && event.getClickCount() == 1) {
|
||||
List<TreePath> paths = new ArrayList<>(Arrays.asList(selectionModel.getSelectionPaths()));
|
||||
|
Loading…
x
Reference in New Issue
Block a user