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; package net.sf.openrocket.file.rocksim.export;
import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.ParallelStage;
import net.sf.openrocket.rocketcomponent.RocketComponent;
public class ParallelStageDTO extends PodSetDTO { 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. * 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) { protected ParallelStageDTO(ParallelStage theORParallelStage) {
super(theORParallelStage, angle); super(theORParallelStage);
setDetachable(true); setDetachable(true);
setEjected(false); setEjected(false);
} }
@ -30,8 +32,8 @@ public class ParallelStageDTO extends PodSetDTO {
public static ParallelStageDTO[] generateParallelStageDTOs(ParallelStage theORParallelStage) { public static ParallelStageDTO[] generateParallelStageDTOs(ParallelStage theORParallelStage) {
ParallelStageDTO[] set = new ParallelStageDTO[theORParallelStage.getInstanceCount()]; ParallelStageDTO[] set = new ParallelStageDTO[theORParallelStage.getInstanceCount()];
int i = 0; int i = 0;
for (double angle : theORParallelStage.getInstanceAngles()) { for (RocketComponent stageInstance : theORParallelStage.splitInstances(false)) {
set[i] = new ParallelStageDTO(theORParallelStage, angle); set[i] = new ParallelStageDTO((ParallelStage) stageInstance);
i++; i++;
} }
return set; 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.PodSet;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.rocketcomponent.Transition;
import net.sf.openrocket.rocketcomponent.position.AnglePositionable;
import net.sf.openrocket.rocketcomponent.position.AxialMethod; import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
@ -57,8 +58,8 @@ public class PodSetDTO extends BasePartDTO implements AttachableParts {
public static PodSetDTO[] generatePodSetDTOs(ComponentAssembly theORPodSet) { public static PodSetDTO[] generatePodSetDTOs(ComponentAssembly theORPodSet) {
PodSetDTO[] set = new PodSetDTO[theORPodSet.getInstanceCount()]; PodSetDTO[] set = new PodSetDTO[theORPodSet.getInstanceCount()];
int i = 0; int i = 0;
for (double angle : theORPodSet.getInstanceAngles()) { for (RocketComponent podInstance : theORPodSet.splitInstances()) {
set[i] = new PodSetDTO(theORPodSet, angle); set[i] = new PodSetDTO((PodSet) podInstance);
i++; i++;
} }
return set; 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. * Copy constructor. Fully populates this instance with values taken from the OR PodSet.
* * This constructor should not be called directly. Instead, use {@link #generatePodSetDTOs}.
* @param theORPodSet * @param theORPodSet the single-instance OR PodSet
*/ */
protected PodSetDTO(ComponentAssembly theORPodSet, double angleOffset) { protected PodSetDTO(ComponentAssembly theORPodSet) {
super(theORPodSet); super(theORPodSet);
// OR should always override the radial angle and distance // OR should always override the radial angle and distance
setAutoCalcRadialDistance(false); setAutoCalcRadialDistance(false);
setAutoCalcRadialAngle(false); setAutoCalcRadialAngle(false);
setDetachable(false); setDetachable(false);
setEjected(false); setEjected(false);
final double angleOffset = theORPodSet.getAngleOffset();
setRadialAngle(angleOffset); setRadialAngle(angleOffset);
setRadialLoc(theORPodSet.getRadiusMethod().getRadius( setRadialLoc(theORPodSet.getRadiusMethod().getRadius(
theORPodSet.getParent(), theORPodSet, theORPodSet.getParent(), theORPodSet,
theORPodSet.getRadiusOffset()) * RockSimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); theORPodSet.getRadiusOffset()) * RockSimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH);
setXb(theORPodSet.getAxialOffset(AxialMethod.TOP) * 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()) { for (RocketComponent child : theORPodSet.getChildren()) {
if (child instanceof PodSet) { if (child instanceof PodSet) {
for (PodSetDTO podSetDTO : generatePodSetDTOs((PodSet) child)) { 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() { public int getAutoCalcRadialDistance() {
return autoCalcRadialDistance; return autoCalcRadialDistance;
} }

View File

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

View File

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