Use pod/booster split for RockSim export

This commit is contained in:
SiboVG 2024-01-24 17:48:39 +01:00
parent 24e72f0bd1
commit e1ab350624
4 changed files with 40 additions and 12 deletions

View File

@ -1,6 +1,7 @@
package net.sf.openrocket.file.rocksim.export;
import net.sf.openrocket.rocketcomponent.ParallelStage;
import net.sf.openrocket.rocketcomponent.RocketComponent;
public class ParallelStageDTO extends PodSetDTO {
@ -12,11 +13,12 @@ public class ParallelStageDTO extends PodSetDTO {
/**
* Copy constructor. Fully populates this instance with values taken from the OR PodSet.
* This constructor should not be called directly. Instead, use {@link #generateParallelStageDTOs}.
*
* @param theORParallelStage
* @param theORParallelStage the single-instance OR ParallelStage
*/
protected ParallelStageDTO(ParallelStage theORParallelStage, double angle) {
super(theORParallelStage, angle);
protected ParallelStageDTO(ParallelStage theORParallelStage) {
super(theORParallelStage);
setDetachable(true);
setEjected(false);
}
@ -30,8 +32,8 @@ public class ParallelStageDTO extends PodSetDTO {
public static ParallelStageDTO[] generateParallelStageDTOs(ParallelStage theORParallelStage) {
ParallelStageDTO[] set = new ParallelStageDTO[theORParallelStage.getInstanceCount()];
int i = 0;
for (double angle : theORParallelStage.getInstanceAngles()) {
set[i] = new ParallelStageDTO(theORParallelStage, angle);
for (RocketComponent stageInstance : theORParallelStage.splitInstances(false)) {
set[i] = new ParallelStageDTO((ParallelStage) stageInstance);
i++;
}
return set;

View File

@ -8,6 +8,7 @@ import net.sf.openrocket.rocketcomponent.ParallelStage;
import net.sf.openrocket.rocketcomponent.PodSet;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.Transition;
import net.sf.openrocket.rocketcomponent.position.AnglePositionable;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import javax.xml.bind.annotation.XmlAccessType;
@ -57,8 +58,8 @@ public class PodSetDTO extends BasePartDTO implements AttachableParts {
public static PodSetDTO[] generatePodSetDTOs(ComponentAssembly theORPodSet) {
PodSetDTO[] set = new PodSetDTO[theORPodSet.getInstanceCount()];
int i = 0;
for (double angle : theORPodSet.getInstanceAngles()) {
set[i] = new PodSetDTO(theORPodSet, angle);
for (RocketComponent podInstance : theORPodSet.splitInstances()) {
set[i] = new PodSetDTO((PodSet) podInstance);
i++;
}
return set;
@ -66,22 +67,27 @@ public class PodSetDTO extends BasePartDTO implements AttachableParts {
/**
* Copy constructor. Fully populates this instance with values taken from the OR PodSet.
*
* @param theORPodSet
* This constructor should not be called directly. Instead, use {@link #generatePodSetDTOs}.
* @param theORPodSet the single-instance OR PodSet
*/
protected PodSetDTO(ComponentAssembly theORPodSet, double angleOffset) {
protected PodSetDTO(ComponentAssembly theORPodSet) {
super(theORPodSet);
// OR should always override the radial angle and distance
setAutoCalcRadialDistance(false);
setAutoCalcRadialAngle(false);
setDetachable(false);
setEjected(false);
final double angleOffset = theORPodSet.getAngleOffset();
setRadialAngle(angleOffset);
setRadialLoc(theORPodSet.getRadiusMethod().getRadius(
theORPodSet.getParent(), theORPodSet,
theORPodSet.getRadiusOffset()) * RockSimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH);
setXb(theORPodSet.getAxialOffset(AxialMethod.TOP) * RockSimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH);
// Children of a PodSet in RockSim do not use angles relative to their PodSet parent, but instead use absolute angle.
// Therefore, we must apply those angles to the children of the PodSet.
addAngleOffsetToChildren(theORPodSet, angleOffset);
for (RocketComponent child : theORPodSet.getChildren()) {
if (child instanceof PodSet) {
for (PodSetDTO podSetDTO : generatePodSetDTOs((PodSet) child)) {
@ -105,6 +111,20 @@ public class PodSetDTO extends BasePartDTO implements AttachableParts {
}
}
private void addAngleOffsetToChildren(RocketComponent component, double angleOffset) {
for (RocketComponent child : component.getChildren()) {
if (child instanceof AnglePositionable anglePositionable) {
anglePositionable.setAngleOffset(anglePositionable.getAngleOffset() + angleOffset);
}
// No need to add an offset to the children of a component assembly. When the component assembly is
// converted to a PodSetDTO, its angle offset will be applied to the children (and that angle offset already
// includes the angle offset of the parent).
if (!(child instanceof ComponentAssembly)) {
addAngleOffsetToChildren(child, angleOffset);
}
}
}
public int getAutoCalcRadialDistance() {
return autoCalcRadialDistance;
}

View File

@ -12,6 +12,7 @@ import javax.xml.bind.Marshaller;
import net.sf.openrocket.logging.ErrorSet;
import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.util.MemoryManagement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -124,6 +125,10 @@ public class RockSimSaver extends RocketSaver {
//Set the last serial number element and reset it.
result.setLastSerialNumber(BasePartDTO.getCurrentSerialNumber());
BasePartDTO.resetCurrentSerialNumber();
// Clean up
MemoryManagement.collectable(rocket);
return result;
}

View File

@ -2462,7 +2462,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
int count = getInstanceCount();
double angleOffset = getAngleOffset();
List<RocketComponent> splitComponents = null; // List of all the split components
List<RocketComponent> splitComponents = new java.util.ArrayList<>(); // List of all the split components
try {
// Freeze rocket
@ -2473,7 +2473,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
// Split the components
if (count > 1) {
parent.removeChild(index, true); // Remove the original component
splitComponents = new java.util.ArrayList<>();
for (int i = 0; i < count; i++) {
RocketComponent copy = this.copy();
copy.setInstanceCount(1);
@ -2486,6 +2485,8 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
splitComponents.add(copy);
}
} else {
splitComponents.add(this);
}
// Split components for listeners