[#1348] Add support for RockSim PodSet importing

This commit is contained in:
SiboVG 2022-11-04 17:49:40 +01:00
parent 13c3e1c6f2
commit 9cea70f517
4 changed files with 97 additions and 4 deletions

View File

@ -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;
}
}

View File

@ -25,6 +25,7 @@ class BodyTubeHandler extends BaseHandler<BodyTube> {
* The OpenRocket BodyTube.
*/
private final BodyTube bodyTube;
private int isInsideTube = 0;
/**
* Constructor.
@ -80,6 +81,9 @@ class BodyTubeHandler extends BaseHandler<BodyTube> {
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<BodyTube> {
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;
}
}

View File

@ -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<PodSet> {
/**
* 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<String, String> 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<String, String> 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;
}
}

View File

@ -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<C extends RocketComponent> 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);