diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/AttachedPartsHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/AttachedPartsHandler.java index 03563fd3d..d90b8b7c5 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/AttachedPartsHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/AttachedPartsHandler.java @@ -8,6 +8,7 @@ import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RockSimCommonConstants; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; +import net.sf.openrocket.rocketcomponent.PodSet; import net.sf.openrocket.rocketcomponent.RocketComponent; import java.util.HashMap; @@ -68,23 +69,32 @@ class AttachedPartsHandler extends AbstractElementHandler { return new RingHandler(context, component, warnings); } if (RockSimCommonConstants.BODY_TUBE.equals(element)) { - return new InnerBodyTubeHandler(context, component, warnings); + // Pods can have BodyTubes as attached parts, but not inner tubes. All other components can't have BodyTubes as + // attached parts. + if (component instanceof PodSet) { + return new BodyTubeHandler(context, component, warnings); + } else { + return new InnerBodyTubeHandler(context, component, warnings); + } } if (RockSimCommonConstants.TRANSITION.equals(element)) { return new TransitionHandler(context, component, warnings); } + if (RockSimCommonConstants.NOSE_CONE.equals(element)) { + return new NoseConeHandler(context, component, warnings); + } if (RockSimCommonConstants.SUBASSEMBLY.equals(element)) { return new SubAssemblyHandler(context, component); } if (RockSimCommonConstants.TUBE_FIN_SET.equals(element)) { return new TubeFinSetHandler(context, component, warnings); } + if (RockSimCommonConstants.EXTERNAL_POD.equals(element)) { + return new PodHandler(context, component, warnings); + } if (RockSimCommonConstants.RING_TAIL.equals(element)) { warnings.add("Ring tails are not currently supported. Ignoring."); } - if (RockSimCommonConstants.EXTERNAL_POD.equals(element)) { - warnings.add("Pods are not currently supported. Ignoring."); - } return null; } } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/BodyTubeHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/BodyTubeHandler.java index 84ed5a8ce..093858955 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/BodyTubeHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/BodyTubeHandler.java @@ -25,6 +25,7 @@ class BodyTubeHandler extends BaseHandler { * The OpenRocket BodyTube. */ private final BodyTube bodyTube; + private int isInsideTube = 0; /** * Constructor. @@ -80,6 +81,9 @@ class BodyTubeHandler extends BaseHandler { if (RockSimCommonConstants.MATERIAL.equals(element)) { setMaterialName(content); } + if (RockSimCommonConstants.IS_INSIDE_TUBE.equals(element)) { + isInsideTube = Integer.parseInt(content); + } } catch (NumberFormatException nfe) { warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); } @@ -104,4 +108,11 @@ class BodyTubeHandler extends BaseHandler { public Material.Type getMaterialType() { return Material.Type.BULK; } + + /** + * Returns 0 if this is a body tube, 1 if it is an inside tube. + */ + public int isInsideTube() { + return isInsideTube; + } } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/PodHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/PodHandler.java new file mode 100644 index 000000000..ffec3d0b5 --- /dev/null +++ b/core/src/net/sf/openrocket/file/rocksim/importt/PodHandler.java @@ -0,0 +1,66 @@ +package net.sf.openrocket.file.rocksim.importt; + +import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; +import net.sf.openrocket.file.rocksim.RockSimCommonConstants; +import net.sf.openrocket.file.simplesax.ElementHandler; +import net.sf.openrocket.file.simplesax.PlainTextHandler; +import net.sf.openrocket.material.Material; +import net.sf.openrocket.rocketcomponent.PodSet; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.rocketcomponent.position.RadiusMethod; +import org.xml.sax.SAXException; + +import java.util.HashMap; + +public class PodHandler extends PositionDependentHandler { + /** + * The OpenRocket BodyTube. + */ + private final PodSet podSet; + + public PodHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) { + super(context); + if (c == null) { + throw new IllegalArgumentException("The parent component of a pod set may not be null."); + } + podSet = new PodSet(); + podSet.setInstanceCount(1); // RockSim only supports one pod instance + podSet.setRadiusMethod(RadiusMethod.FREE); // RockSim radial offset is relative to the center of the parent + if (isCompatible(c, PodSet.class, warnings)) { + c.addChild(podSet); + } + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) throws SAXException { + if (RockSimCommonConstants.BODY_TUBE.equals(element)) { // RockSim pods allow body tubes, not inner tubes + return new BodyTubeHandler(context, podSet, warnings); + } + if (RockSimCommonConstants.ATTACHED_PARTS.equals(element)) { + return new AttachedPartsHandler(context, podSet); + } + return PlainTextHandler.INSTANCE; + } + + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException { + super.closeElement(element, attributes, content, warnings); + if (RockSimCommonConstants.RADIAL_ANGLE.equals(element)) { + podSet.setAngleOffset(Double.parseDouble(content)); + } + if (RockSimCommonConstants.RADIAL_LOC.equals(element)) { + podSet.setRadiusOffset(Double.parseDouble(content) / RockSimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + } + } + + @Override + protected PodSet getComponent() { + return podSet; + } + + @Override + protected Material.Type getMaterialType() { + return Material.Type.BULK; + } +} diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/PositionDependentHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/PositionDependentHandler.java index c5c5ae7ba..2bdd3a674 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/PositionDependentHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/PositionDependentHandler.java @@ -9,6 +9,8 @@ import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RockSimCommonConstants; import net.sf.openrocket.file.rocksim.RockSimLocationMode; +import net.sf.openrocket.rocketcomponent.ComponentAssembly; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.position.AxialMethod; @@ -70,6 +72,10 @@ public abstract class PositionDependentHandler extend * Set the axialMethod of a component. */ protected void setLocation() { + if ((getComponent() instanceof ComponentAssembly || getComponent() instanceof ParallelStage) && + getComponent().getParent() == null) { + return; + } getComponent().setAxialMethod(axialMethod); if (axialMethod.equals(AxialMethod.BOTTOM)) { getComponent().setAxialOffset(-1d * positionValue);