DGP - added isCompatible checks for all Rocksim components
authorrodinia814 <rodinia814@180e2498-e6e9-4542-8430-84ac67f01cd8>
Tue, 20 Jul 2010 06:13:55 +0000 (06:13 +0000)
committerrodinia814 <rodinia814@180e2498-e6e9-4542-8430-84ac67f01cd8>
Tue, 20 Jul 2010 06:13:55 +0000 (06:13 +0000)
git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@59 180e2498-e6e9-4542-8430-84ac67f01cd8

24 files changed:
src/net/sf/openrocket/file/rocksim/AttachedPartsHandler.java
src/net/sf/openrocket/file/rocksim/BaseHandler.java
src/net/sf/openrocket/file/rocksim/BodyTubeHandler.java
src/net/sf/openrocket/file/rocksim/FinSetHandler.java
src/net/sf/openrocket/file/rocksim/InnerBodyTubeHandler.java
src/net/sf/openrocket/file/rocksim/LaunchLugHandler.java
src/net/sf/openrocket/file/rocksim/MassObjectHandler.java
src/net/sf/openrocket/file/rocksim/NoseConeHandler.java
src/net/sf/openrocket/file/rocksim/ParachuteHandler.java
src/net/sf/openrocket/file/rocksim/RingHandler.java
src/net/sf/openrocket/file/rocksim/RocksimHandler.java
src/net/sf/openrocket/file/rocksim/StreamerHandler.java
src/net/sf/openrocket/file/rocksim/TransitionHandler.java
test/net/sf/openrocket/file/rocksim/BodyTubeHandlerTest.java
test/net/sf/openrocket/file/rocksim/InnerBodyTubeHandlerTest.java
test/net/sf/openrocket/file/rocksim/LaunchLugHandlerTest.java
test/net/sf/openrocket/file/rocksim/MassObjectHandlerTest.java
test/net/sf/openrocket/file/rocksim/NoseConeHandlerTest.java
test/net/sf/openrocket/file/rocksim/ParachuteHandlerTest.java
test/net/sf/openrocket/file/rocksim/PodFins.rkt [new file with mode: 0644]
test/net/sf/openrocket/file/rocksim/RingHandlerTest.java
test/net/sf/openrocket/file/rocksim/RocksimLoaderTest.java
test/net/sf/openrocket/file/rocksim/StreamerHandlerTest.java
test/net/sf/openrocket/file/rocksim/TransitionHandlerTest.java

index 76085748f56f87e69907f84ff74c9b53f9147717..2ced5a7e1d5da3b7a1c3f1a541dc76e0c24ff73e 100644 (file)
@@ -39,25 +39,25 @@ class AttachedPartsHandler extends ElementHandler {
             return new FinSetHandler(component);
         }
         if ("LaunchLug".equals(element)) {
-            return new LaunchLugHandler(component);
+            return new LaunchLugHandler(component, warnings);
         }
         if ("Parachute".equals(element)) {
-            return new ParachuteHandler(component);
+            return new ParachuteHandler(component, warnings);
         }
         if ("Streamer".equals(element)) {
-            return new StreamerHandler(component);
+            return new StreamerHandler(component, warnings);
         }
         if ("MassObject".equals(element)) {
-            return new MassObjectHandler(component);
+            return new MassObjectHandler(component, warnings);
         }
         if ("Ring".equals(element)) {
-            return new RingHandler(component);
+            return new RingHandler(component, warnings);
         }
         if ("BodyTube".equals(element)) {
-            return new InnerBodyTubeHandler(component);
+            return new InnerBodyTubeHandler(component, warnings);
         }
         if ("Transition".equals(element)) {
-            return new TransitionHandler(component);
+            return new TransitionHandler(component, warnings);
         }
         if ("TubeFinSet".equals(element)) {
             warnings.add("Tube fins are not currently supported. Ignoring.");
index 700c2f9bdbcec4b38795d45b017d9bb932c35b93..c4e9c11e403efadd9d9cbf6fe1f4526b33587d1c 100644 (file)
@@ -180,6 +180,26 @@ public abstract class BaseHandler<C extends RocketComponent> extends ElementHand
         materialName = content;
     }
 
+    /**
+     * Add child to parent only if the child is compatible.  Otherwise add to warning set.
+     * 
+     * @param parent  the parent component
+     * @param child   the child component
+     * @param warnings the warning set
+     * 
+     * @return true if the child is compatible with parent
+     */
+    protected static boolean isCompatible(RocketComponent parent, Class<? extends RocketComponent> child, WarningSet warnings) {
+        if (!parent.isCompatible(child)) {
+            warnings.add(child.getName() + " can not be attached to "
+                         + parent.getComponentName() + ", ignoring component.");
+            return false;
+        }
+        else {
+            return true;
+        }
+    }
+    
     /**
      * Create a custom material based on the density.
      *
index 6347d3b2a9f66b31b468524ef2a9598cc2609a2a..a645827f37a23b54bda45bd1fb52eefb9b6ebe78 100644 (file)
@@ -26,14 +26,17 @@ class BodyTubeHandler extends BaseHandler<BodyTube> {
      * Constructor.
      *
      * @param c parent component
+     * @param warnings  the warning set
      * @throws IllegalArgumentException thrown if <code>c</code> is null
      */
-    public BodyTubeHandler(RocketComponent c) throws IllegalArgumentException {
+    public BodyTubeHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
         if (c == null) {
             throw new IllegalArgumentException("The parent component of a body tube may not be null.");
         }
         bodyTube = new BodyTube();
-        c.addChild(bodyTube);
+        if (isCompatible(c, BodyTube.class, warnings)) {
+            c.addChild(bodyTube);
+        }
     }
 
     @Override
index fb8add582277643ce564bf69edaff7fb634c9e19..9b9239dc49ccc9641d7bcca7a5aeba4dccb15622 100644 (file)
@@ -7,26 +7,26 @@ import net.sf.openrocket.aerodynamics.WarningSet;
 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.RocketComponent;
-import net.sf.openrocket.rocketcomponent.FinSet;
-import net.sf.openrocket.rocketcomponent.ExternalComponent;
-import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
 import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
+import net.sf.openrocket.rocketcomponent.ExternalComponent;
+import net.sf.openrocket.rocketcomponent.FinSet;
 import net.sf.openrocket.rocketcomponent.FreeformFinSet;
 import net.sf.openrocket.rocketcomponent.IllegalFinPointException;
+import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
 import net.sf.openrocket.util.Coordinate;
 import org.xml.sax.SAXException;
 
-import java.util.HashMap;
-import java.util.List;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
 
 /**
- * A SAX handler for Rocksim fin sets.  Because the type of
- * fin may not be known first (in Rocksim file format, the fin shape type is in the middle of the XML structure),
- * and because we're using SAX not DOM, all of the fin characteristics are kept here until the closing FinSet tag.
- * At that point, <code>asOpenRocket</code> method is called to construct the corresponding OpenRocket FinSet.
+ * A SAX handler for Rocksim fin sets.  Because the type of fin may not be known first (in Rocksim file format, the fin
+ * shape type is in the middle of the XML structure), and because we're using SAX not DOM, all of the fin
+ * characteristics are kept here until the closing FinSet tag. At that point, <code>asOpenRocket</code> method is called
+ * to construct the corresponding OpenRocket FinSet.
  */
 class FinSetHandler extends ElementHandler {
     /**
@@ -47,7 +47,7 @@ class FinSetHandler extends ElementHandler {
      */
     private double location = 0.0d;
     /**
-     * The OpenRocket Position which gives the absolute/relative positiong for location.
+     * The OpenRocket Position which gives the absolute/relative positioning for location.
      */
     private RocketComponent.Position position;
     /**
@@ -141,9 +141,9 @@ class FinSetHandler extends ElementHandler {
      *
      * @param c the parent
      *
-     * @throws IllegalArgumentException  thrown if <code>c</code> is null
+     * @throws IllegalArgumentException thrown if <code>c</code> is null
      */
-    public FinSetHandler(RocketComponent c) throws IllegalArgumentException {
+    public FinSetHandler (RocketComponent c) throws IllegalArgumentException {
         if (c == null) {
             throw new IllegalArgumentException("The parent component of a fin set may not be null.");
         }
@@ -151,12 +151,12 @@ class FinSetHandler extends ElementHandler {
     }
 
     @Override
-    public ElementHandler openElement(String element, HashMap<String, String> attributes, WarningSet warnings) {
+    public ElementHandler openElement (String element, HashMap<String, String> attributes, WarningSet warnings) {
         return PlainTextHandler.INSTANCE;
     }
 
     @Override
-    public void closeElement(String element, HashMap<String, String> attributes, String content, WarningSet warnings)
+    public void closeElement (String element, HashMap<String, String> attributes, String content, WarningSet warnings)
             throws SAXException {
         try {
             if ("Name".equals(element)) {
@@ -241,20 +241,26 @@ class FinSetHandler extends ElementHandler {
     }
 
     @Override
-    public void endHandler(String element, HashMap<String, String> attributes,
-                           String content, WarningSet warnings) throws SAXException {
+    public void endHandler (String element, HashMap<String, String> attributes,
+            String content, WarningSet warnings) throws SAXException {
         //Create the fin set and correct for overrides and actual material densities
         final FinSet finSet = asOpenRocket(warnings);
-        BaseHandler.setOverride(finSet, override, mass, cg);
-        if (!override && finSet.getCrossSection().equals(FinSet.CrossSection.AIRFOIL)) {
-            //Override mass anyway.  This is done only for AIRFOIL because Rocksim does not compute different
-            //mass/cg for different cross sections, but OpenRocket does.  This can lead to drastic differences
-            //in mass.  To counteract that, the cross section value is retained but the mass/cg is overridden
-            //with the calculated values from Rocksim.  This will best approximate the Rocksim design in OpenRocket.
-            BaseHandler.setOverride(finSet, true, calcMass, calcCg);
+        if (component.isCompatible(finSet)) {
+            BaseHandler.setOverride(finSet, override, mass, cg);
+            if (!override && finSet.getCrossSection().equals(FinSet.CrossSection.AIRFOIL)) {
+                //Override mass anyway.  This is done only for AIRFOIL because Rocksim does not compute different
+                //mass/cg for different cross sections, but OpenRocket does.  This can lead to drastic differences
+                //in mass.  To counteract that, the cross section value is retained but the mass/cg is overridden
+                //with the calculated values from Rocksim.  This will best approximate the Rocksim design in OpenRocket.
+                BaseHandler.setOverride(finSet, true, calcMass, calcCg);
+            }
+            BaseHandler.updateComponentMaterial(finSet, materialName, Material.Type.BULK, density);
+            component.addChild(finSet);
+        }
+        else {
+            warnings.add(finSet.getComponentName() + " can not be attached to "
+                         + component.getComponentName() + ", ignoring component.");
         }
-        BaseHandler.updateComponentMaterial(finSet, materialName, Material.Type.BULK, density);
-        component.addChild(finSet);
     }
 
 
@@ -262,9 +268,10 @@ class FinSetHandler extends ElementHandler {
      * Convert the parsed Rocksim data values in this object to an instance of OpenRocket's FinSet.
      *
      * @param warnings the warning set to convey incompatibilities to the user
+     *
      * @return a FinSet instance
      */
-    public FinSet asOpenRocket(WarningSet warnings) {
+    public FinSet asOpenRocket (WarningSet warnings) {
         FinSet result;
 
         if (shapeCode == 0) {
@@ -313,26 +320,26 @@ class FinSetHandler extends ElementHandler {
      *
      * @param pointList a comma and pipe delimited string of X,Y coordinates from Rocksim.  This is of the format:
      *                  <pre>x0,y0|x1,y1|x2,y2|... </pre>
-     * @param warnings the warning set to convey incompatibilities to the user
+     * @param warnings  the warning set to convey incompatibilities to the user
      *
      * @return an array of OpenRocket Coordinates
      */
-    private Coordinate[] toCoordinates(String pointList, WarningSet warnings) {
+    private Coordinate[] toCoordinates (String pointList, WarningSet warnings) {
         List<Coordinate> result = new ArrayList<Coordinate>();
         if (pointList != null && !pointList.isEmpty()) {
             String[] points = pointList.split("\\Q|\\E");
             for (String point : points) {
                 String[] aPoint = point.split(",");
                 try {
-                if (aPoint.length > 1) {
-                    Coordinate c = new Coordinate(
-                            Double.parseDouble(aPoint[0]) / RocksimHandler.ROCKSIM_TO_OPENROCKET_LENGTH,
-                            Double.parseDouble(aPoint[1]) / RocksimHandler.ROCKSIM_TO_OPENROCKET_LENGTH);
-                    result.add(c);
-                }
-                else {
-                    warnings.add("Invalid fin point pair.");
-                }
+                    if (aPoint.length > 1) {
+                        Coordinate c = new Coordinate(
+                                Double.parseDouble(aPoint[0]) / RocksimHandler.ROCKSIM_TO_OPENROCKET_LENGTH,
+                                Double.parseDouble(aPoint[1]) / RocksimHandler.ROCKSIM_TO_OPENROCKET_LENGTH);
+                        result.add(c);
+                    }
+                    else {
+                        warnings.add("Invalid fin point pair.");
+                    }
                 }
                 catch (NumberFormatException nfe) {
                     warnings.add("Fin point not in numeric format.");
@@ -356,9 +363,10 @@ class FinSetHandler extends ElementHandler {
      * Convert a Rocksim tip shape to an OpenRocket CrossSection.
      *
      * @param tipShape the tip shape code from Rocksim
+     *
      * @return a CrossSection instance
      */
-    private FinSet.CrossSection convertTipShapeCode(int tipShape) {
+    private FinSet.CrossSection convertTipShapeCode (int tipShape) {
         switch (tipShape) {
             case 0:
                 return FinSet.CrossSection.SQUARE;
index 1c7b41c2157d6725a4daa9c20d0db486dc8d073d..eaa10148bdf54019d5eb46c0755a11096d0fe7e6 100644 (file)
@@ -27,14 +27,17 @@ class InnerBodyTubeHandler extends PositionDependentHandler<InnerTube> {
      * Constructor.
      *
      * @param c the parent component
+     * @param warnings  the warning set
      * @throws IllegalArgumentException thrown if <code>c</code> is null
      */
-    public InnerBodyTubeHandler(RocketComponent c) throws IllegalArgumentException {
+    public InnerBodyTubeHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
         if (c == null) {
             throw new IllegalArgumentException("The parent component of an inner tube may not be null.");
         }
         bodyTube = new InnerTube();
-        c.addChild(bodyTube);
+        if (isCompatible(c, InnerTube.class, warnings)) {
+            c.addChild(bodyTube);
+        }
     }
 
     @Override
index 969cfdbf3ef6883657c49444ca52206dc1d91fc6..049feedd8579b4fd05f6a629938a1bde28cf9428 100644 (file)
@@ -27,14 +27,18 @@ class LaunchLugHandler extends PositionDependentHandler<LaunchLug> {
      * Constructor.
      *
      * @param c the parent
+     * @param warnings  the warning set
+     * 
      * @throws IllegalArgumentException thrown if <code>c</code> is null
      */
-    public LaunchLugHandler(RocketComponent c) throws IllegalArgumentException {
+    public LaunchLugHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
         if (c == null) {
             throw new IllegalArgumentException("The parent component of a launch lug may not be null.");
         }
         lug = new LaunchLug();
-        c.addChild(lug);
+        if (isCompatible(c, LaunchLug.class, warnings)) {
+            c.addChild(lug);
+        }
     }
 
     @Override
index 31ddef7059657e3522fdf8e64c49beaa3a022b9c..479242d954529b4a254e18ce7079644502d1c8d8 100644 (file)
@@ -36,15 +36,18 @@ class MassObjectHandler extends PositionDependentHandler<MassComponent> {
      * Constructor.
      *l
      * @param c the parent component
+     * @param warnings  the warning set
      * 
      * @throws IllegalArgumentException  thrown if <code>c</code> is null
      */
-    public MassObjectHandler(RocketComponent c) throws IllegalArgumentException {
+    public MassObjectHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
         if (c == null) {
             throw new IllegalArgumentException("The parent component of a mass component may not be null.");
         }
         mass = new MassComponent();
-        c.addChild(mass);
+        if (isCompatible(c, MassComponent.class, warnings)) {
+            c.addChild(mass);
+        }
     }
 
     @Override
index 6dc4efa37ba8411271fb5bd219f71f60968360da..ec5c2df76a17a525457fb56332072d2dfc2d050a 100644 (file)
@@ -33,14 +33,18 @@ class NoseConeHandler extends BaseHandler<NoseCone> {
      * Constructor.
      *
      * @param c the parent component to the nosecone
+     * @param warnings  the warning set
+     * 
      * @throws IllegalArgumentException thrown if <code>c</code> is null
      */
-    public NoseConeHandler(RocketComponent c) throws IllegalArgumentException {
+    public NoseConeHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
         if (c == null) {
             throw new IllegalArgumentException("The parent component of a nose cone may not be null.");
         }
-        c.addChild(noseCone);
-        noseCone.setAftRadiusAutomatic(false);
+        if (isCompatible(c, NoseCone.class, warnings)) {
+            c.addChild(noseCone);
+            noseCone.setAftRadiusAutomatic(false);
+        }
     }
 
     @Override
index 6cadaff56cdd3fbd3b800b638c2802170f709da0..44418faefe05ea15f86ae8b9d17c8be58fcac82d 100644 (file)
@@ -32,14 +32,18 @@ class ParachuteHandler extends RecoveryDeviceHandler<Parachute> {
      * Constructor.
      *
      * @param c the parent component
+     * @param warnings  the warning set
+     * 
      * @throws IllegalArgumentException thrown if <code>c</code> is null
      */
-    public ParachuteHandler(RocketComponent c) throws IllegalArgumentException {
+    public ParachuteHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
         if (c == null) {
             throw new IllegalArgumentException("The parent of a parachute may not be null.");
         }
         chute = new Parachute();
-        c.addChild(chute);
+        if (isCompatible(c, Parachute.class, warnings)) {
+            c.addChild(chute);
+        }
     }
 
     /**
index ccfcfb06916b1e0fe5c592e02007d9c5226a98a1..22394201bda21032c66bf560c4b4d8f43014886d 100644 (file)
@@ -27,14 +27,17 @@ class RingHandler extends PositionDependentHandler<CenteringRing> {
      * Constructor.
      *
      * @param c the parent component
+     * @param warnings  the warning set
      * @throws IllegalArgumentException thrown if <code>c</code> is null
      */
-    public RingHandler(RocketComponent c) throws IllegalArgumentException {
+    public RingHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
         if (c == null) {
             throw new IllegalArgumentException("The parent of a ring may not be null.");
         }
         ring = new CenteringRing();
-        c.addChild(ring);
+        if (isCompatible(c, CenteringRing.class, warnings)) {
+            c.addChild(ring);
+        }
     }
 
     @Override
index 51c20514f8503c975d03fa0fb580e3fa225a4327..7198b90f9eca600455e0d0839c3d5b7fcd5b02f0 100644 (file)
@@ -360,13 +360,13 @@ class StageHandler extends ElementHandler {
     @Override
     public ElementHandler openElement(String element, HashMap<String, String> attributes, WarningSet warnings) {
         if ("NoseCone".equals(element)) {
-            return new NoseConeHandler(component);
+            return new NoseConeHandler(component, warnings);
         }
         if ("BodyTube".equals(element)) {
-            return new BodyTubeHandler(component);
+            return new BodyTubeHandler(component, warnings);
         }
         if ("Transition".equals(element)) {
-            return new TransitionHandler(component);
+            return new TransitionHandler(component, warnings);
         }
         return null;
     }
index d638f62bc44f36c55969dd5ba006ba7d150fa1ab..73a8c2e8b6c83df26a828747290f0ddd794e62a9 100644 (file)
@@ -26,14 +26,18 @@ class StreamerHandler extends RecoveryDeviceHandler<Streamer> {
      * Constructor.
      *
      * @param c the parent component
+     * @param warnings  the warning set
+     * 
      * @throws IllegalArgumentException thrown if <code>c</code> is null
      */
-    public StreamerHandler(RocketComponent c) throws IllegalArgumentException {
+    public StreamerHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
         if (c == null) {
             throw new IllegalArgumentException("The parent of a streamer may not be null.");
         }
         streamer = new Streamer();
-        c.addChild(streamer);
+        if (isCompatible(c, Streamer.class, warnings)) {
+            c.addChild(streamer);
+        }
     }
 
     /**
index 1f3b02e1572621623c5f80edfcf262c22ff38cb9..54ea3237a2f60e4f7e21c9bf4698fb2f2769f989 100644 (file)
@@ -31,13 +31,16 @@ class TransitionHandler extends BaseHandler<Transition> {
      * Constructor.
      *
      * @param c the parent component
+     * @param warnings  the warning set
      * @throws IllegalArgumentException thrown if <code>c</code> is null
      */
-    public TransitionHandler(RocketComponent c) throws IllegalArgumentException {
+    public TransitionHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
         if (c == null) {
             throw new IllegalArgumentException("The parent of a transition may not be null.");
         }
-        c.addChild(transition);
+        if (isCompatible(c, Transition.class, warnings)) {
+            c.addChild(transition);
+        }
     }
 
     @Override
index 915ed03d6fc147b0d06fa4a40ac30a79ebc7c36b..8cbd6f783171ba56848c0aa78678991e09bef9f8 100644 (file)
@@ -6,12 +6,11 @@ package net.sf.openrocket.file.rocksim;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import net.sf.openrocket.aerodynamics.WarningSet;
-import net.sf.openrocket.database.Databases;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.BodyTube;
-import net.sf.openrocket.rocketcomponent.Stage;
 import net.sf.openrocket.rocketcomponent.ExternalComponent;
+import net.sf.openrocket.rocketcomponent.Stage;
 
 import java.util.HashMap;
 
@@ -72,7 +71,7 @@ public class BodyTubeHandlerTest extends RocksimTestBase {
     public void testConstructor() throws Exception {
 
         try {
-            new BodyTubeHandler(null);
+            new BodyTubeHandler(null, new WarningSet());
             fail("Should have thrown IllegalArgumentException");
         }
         catch (IllegalArgumentException iae) {
@@ -80,7 +79,7 @@ public class BodyTubeHandlerTest extends RocksimTestBase {
         }
 
         Stage stage = new Stage();
-        BodyTubeHandler handler = new BodyTubeHandler(stage);
+        BodyTubeHandler handler = new BodyTubeHandler(stage, new WarningSet());
         BodyTube component = (BodyTube) getField(handler, "bodyTube");
         assertContains(component, stage.getChildren());
     }
@@ -91,8 +90,8 @@ public class BodyTubeHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testOpenElement() throws Exception {
-        assertEquals(PlainTextHandler.INSTANCE, new BodyTubeHandler(new Stage()).openElement(null, null, null));
-        assertNotNull(new BodyTubeHandler(new Stage()).openElement("AttachedParts", null, null));
+        assertEquals(PlainTextHandler.INSTANCE, new BodyTubeHandler(new Stage(), new WarningSet()).openElement(null, null, null));
+        assertNotNull(new BodyTubeHandler(new Stage(), new WarningSet()).openElement("AttachedParts", null, null));
     }
 
     /**
@@ -103,7 +102,7 @@ public class BodyTubeHandlerTest extends RocksimTestBase {
      */
     public void testCloseElement() throws Exception {
         Stage stage = new Stage();
-        BodyTubeHandler handler = new BodyTubeHandler(stage);
+        BodyTubeHandler handler = new BodyTubeHandler(stage, new WarningSet());
         BodyTube component = (BodyTube) getField(handler, "bodyTube");
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
@@ -173,7 +172,7 @@ public class BodyTubeHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetComponent() throws Exception {
-        assertTrue(new BodyTubeHandler(new Stage()).getComponent() instanceof BodyTube);
+        assertTrue(new BodyTubeHandler(new Stage(), new WarningSet()).getComponent() instanceof BodyTube);
     }
 
     /**
@@ -182,7 +181,7 @@ public class BodyTubeHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetMaterialType() throws Exception {
-        assertEquals(Material.Type.BULK, new BodyTubeHandler(new Stage()).getMaterialType());
+        assertEquals(Material.Type.BULK, new BodyTubeHandler(new Stage(), new WarningSet()).getMaterialType());
     }
 
 }
index 5a8827e364af459fd33d6697b1e5b925f3e35891..d8d892c695125e7490f30331452cdbb93490b90c 100644 (file)
@@ -6,13 +6,11 @@ package net.sf.openrocket.file.rocksim;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import net.sf.openrocket.aerodynamics.WarningSet;
-import net.sf.openrocket.database.Databases;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.BodyTube;
 import net.sf.openrocket.rocketcomponent.InnerTube;
 import net.sf.openrocket.rocketcomponent.RocketComponent;
-import net.sf.openrocket.rocketcomponent.Stage;
 
 import java.util.HashMap;
 
@@ -73,7 +71,7 @@ public class InnerBodyTubeHandlerTest extends RocksimTestBase {
     public void testConstructor() throws Exception {
 
         try {
-            new InnerBodyTubeHandler(null);
+            new InnerBodyTubeHandler(null, new WarningSet());
             fail("Should have thrown IllegalArgumentException");
         }
         catch (IllegalArgumentException iae) {
@@ -81,7 +79,7 @@ public class InnerBodyTubeHandlerTest extends RocksimTestBase {
         }
 
         BodyTube tube = new BodyTube();
-        InnerBodyTubeHandler handler = new InnerBodyTubeHandler(tube);
+        InnerBodyTubeHandler handler = new InnerBodyTubeHandler(tube, new WarningSet());
         InnerTube component = (InnerTube) getField(handler, "bodyTube");
         assertContains(component, tube.getChildren());
     }
@@ -92,8 +90,8 @@ public class InnerBodyTubeHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testOpenElement() throws Exception {
-        assertEquals(PlainTextHandler.INSTANCE, new InnerBodyTubeHandler(new BodyTube()).openElement(null, null, null));
-        assertNotNull(new InnerBodyTubeHandler(new BodyTube()).openElement("AttachedParts", null, null));
+        assertEquals(PlainTextHandler.INSTANCE, new InnerBodyTubeHandler(new BodyTube(), new WarningSet()).openElement(null, null, null));
+        assertNotNull(new InnerBodyTubeHandler(new BodyTube(), new WarningSet()).openElement("AttachedParts", null, null));
     }
 
     /**
@@ -104,7 +102,7 @@ public class InnerBodyTubeHandlerTest extends RocksimTestBase {
      */
     public void testCloseElement() throws Exception {
         BodyTube tube = new BodyTube();
-        InnerBodyTubeHandler handler = new InnerBodyTubeHandler(tube);
+        InnerBodyTubeHandler handler = new InnerBodyTubeHandler(tube, new WarningSet());
         InnerTube component = (InnerTube) getField(handler, "bodyTube");
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
@@ -167,7 +165,7 @@ public class InnerBodyTubeHandlerTest extends RocksimTestBase {
      */
     public void testSetRelativePosition() throws Exception {
         BodyTube tube = new BodyTube();
-        InnerBodyTubeHandler handler = new InnerBodyTubeHandler(tube);
+        InnerBodyTubeHandler handler = new InnerBodyTubeHandler(tube, new WarningSet());
         InnerTube component = (InnerTube) getField(handler, "bodyTube");
         handler.setRelativePosition(RocketComponent.Position.ABSOLUTE);
         assertEquals(RocketComponent.Position.ABSOLUTE, component.getRelativePosition());
@@ -179,7 +177,7 @@ public class InnerBodyTubeHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetComponent() throws Exception {
-        assertTrue(new InnerBodyTubeHandler(new BodyTube()).getComponent() instanceof InnerTube);
+        assertTrue(new InnerBodyTubeHandler(new BodyTube(), new WarningSet()).getComponent() instanceof InnerTube);
     }
 
     /**
@@ -188,7 +186,7 @@ public class InnerBodyTubeHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetMaterialType() throws Exception {
-        assertEquals(Material.Type.BULK, new InnerBodyTubeHandler(new BodyTube()).getMaterialType());
+        assertEquals(Material.Type.BULK, new InnerBodyTubeHandler(new BodyTube(), new WarningSet()).getMaterialType());
     }
 
 
index 6eb3263b8670abfafbbaf76c660d08be1c5f393d..689c86f231560f3f3f387d241801d7ccf7f4f72d 100644 (file)
@@ -6,7 +6,6 @@ package net.sf.openrocket.file.rocksim;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import net.sf.openrocket.aerodynamics.WarningSet;
-import net.sf.openrocket.database.Databases;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.BodyTube;
@@ -72,7 +71,7 @@ public class LaunchLugHandlerTest extends RocksimTestBase {
     public void testConstructor() throws Exception {
 
         try {
-            new LaunchLugHandler(null);
+            new LaunchLugHandler(null, new WarningSet());
             fail("Should have thrown IllegalArgumentException");
         }
         catch (IllegalArgumentException iae) {
@@ -80,7 +79,7 @@ public class LaunchLugHandlerTest extends RocksimTestBase {
         }
 
         BodyTube tube = new BodyTube();
-        LaunchLugHandler handler = new LaunchLugHandler(tube);
+        LaunchLugHandler handler = new LaunchLugHandler(tube, new WarningSet());
         LaunchLug component = (LaunchLug) getField(handler, "lug");
         assertContains(component, tube.getChildren());
     }
@@ -91,7 +90,7 @@ public class LaunchLugHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testOpenElement() throws Exception {
-        assertEquals(PlainTextHandler.INSTANCE, new LaunchLugHandler(new BodyTube()).openElement(null, null, null));
+        assertEquals(PlainTextHandler.INSTANCE, new LaunchLugHandler(new BodyTube(), new WarningSet()).openElement(null, null, null));
     }
 
     /**
@@ -102,7 +101,7 @@ public class LaunchLugHandlerTest extends RocksimTestBase {
      */
     public void testCloseElement() throws Exception {
         BodyTube tube = new BodyTube();
-        LaunchLugHandler handler = new LaunchLugHandler(tube);
+        LaunchLugHandler handler = new LaunchLugHandler(tube, new WarningSet());
         LaunchLug component = (LaunchLug) getField(handler, "lug");
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
@@ -156,7 +155,7 @@ public class LaunchLugHandlerTest extends RocksimTestBase {
      */
     public void testSetRelativePosition() throws Exception {
         BodyTube tube = new BodyTube();
-        LaunchLugHandler handler = new LaunchLugHandler(tube);
+        LaunchLugHandler handler = new LaunchLugHandler(tube, new WarningSet());
         LaunchLug component = (LaunchLug) getField(handler, "lug");
         handler.setRelativePosition(RocketComponent.Position.ABSOLUTE);
         assertEquals(RocketComponent.Position.ABSOLUTE, component.getRelativePosition());
@@ -168,7 +167,7 @@ public class LaunchLugHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetComponent() throws Exception {
-        assertTrue(new LaunchLugHandler(new BodyTube()).getComponent() instanceof LaunchLug);
+        assertTrue(new LaunchLugHandler(new BodyTube(), new WarningSet()).getComponent() instanceof LaunchLug);
     }
 
     /**
@@ -177,7 +176,7 @@ public class LaunchLugHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetMaterialType() throws Exception {
-        assertEquals(Material.Type.BULK, new LaunchLugHandler(new BodyTube()).getMaterialType());
+        assertEquals(Material.Type.BULK, new LaunchLugHandler(new BodyTube(), new WarningSet()).getMaterialType());
     }
 
 
index ce4bdded3f83b59ddc5128386316ec3b943d428b..36f17c11ac38d9d46dc6df1f764f140a73b6ec79 100644 (file)
@@ -5,15 +5,12 @@ package net.sf.openrocket.file.rocksim;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
+import net.sf.openrocket.aerodynamics.WarningSet;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.BodyTube;
 import net.sf.openrocket.rocketcomponent.MassComponent;
 import net.sf.openrocket.rocketcomponent.RocketComponent;
-import net.sf.openrocket.rocketcomponent.Stage;
-import net.sf.openrocket.rocketcomponent.NoseCone;
-import net.sf.openrocket.rocketcomponent.Transition;
-import net.sf.openrocket.aerodynamics.WarningSet;
 
 import java.util.HashMap;
 
@@ -73,7 +70,7 @@ public class MassObjectHandlerTest extends RocksimTestBase {
     public void testConstructor() throws Exception {
 
         try {
-            new MassObjectHandler(null);
+            new MassObjectHandler(null, new WarningSet());
             fail("Should have thrown IllegalArgumentException");
         }
         catch (IllegalArgumentException iae) {
@@ -81,7 +78,7 @@ public class MassObjectHandlerTest extends RocksimTestBase {
         }
 
         BodyTube tube = new BodyTube();
-        MassObjectHandler handler = new MassObjectHandler(tube);
+        MassObjectHandler handler = new MassObjectHandler(tube, new WarningSet());
         MassComponent component = (MassComponent) getField(handler, "mass");
         assertContains(component, tube.getChildren());
     }
@@ -92,7 +89,7 @@ public class MassObjectHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testOpenElement() throws Exception {
-        assertEquals(PlainTextHandler.INSTANCE, new MassObjectHandler(new BodyTube()).openElement(null, null, null));
+        assertEquals(PlainTextHandler.INSTANCE, new MassObjectHandler(new BodyTube(), new WarningSet()).openElement(null, null, null));
     }
 
     /**
@@ -106,7 +103,7 @@ public class MassObjectHandlerTest extends RocksimTestBase {
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
 
-        MassObjectHandler handler = new MassObjectHandler(tube);
+        MassObjectHandler handler = new MassObjectHandler(tube, new WarningSet());
         MassComponent component = (MassComponent) getField(handler, "mass");
 
         handler.closeElement("Len", attributes, "-1", warnings);
@@ -138,7 +135,7 @@ public class MassObjectHandlerTest extends RocksimTestBase {
      */
     public void testSetRelativePosition() throws Exception {
         BodyTube tube = new BodyTube();
-        MassObjectHandler handler = new MassObjectHandler(tube);
+        MassObjectHandler handler = new MassObjectHandler(tube, new WarningSet());
         MassComponent component = (MassComponent) getField(handler, "mass");
         handler.setRelativePosition(RocketComponent.Position.ABSOLUTE);
         assertEquals(RocketComponent.Position.ABSOLUTE, component.getRelativePosition());
@@ -150,7 +147,7 @@ public class MassObjectHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetComponent() throws Exception {
-        assertTrue(new MassObjectHandler(new BodyTube()).getComponent() instanceof MassComponent);
+        assertTrue(new MassObjectHandler(new BodyTube(), new WarningSet()).getComponent() instanceof MassComponent);
     }
 
     /**
@@ -159,7 +156,7 @@ public class MassObjectHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetMaterialType() throws Exception {
-        assertEquals(Material.Type.BULK, new MassObjectHandler(new BodyTube()).getMaterialType());
+        assertEquals(Material.Type.BULK, new MassObjectHandler(new BodyTube(), new WarningSet()).getMaterialType());
     }
 
 
index 9cce15d32daf4eda24f29836394b53bdb5ad02f2..75bc914641ed05d1d11fe2c89924f04c6623ef40 100644 (file)
@@ -5,14 +5,13 @@ package net.sf.openrocket.file.rocksim;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
+import net.sf.openrocket.aerodynamics.WarningSet;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.material.Material;
+import net.sf.openrocket.rocketcomponent.ExternalComponent;
 import net.sf.openrocket.rocketcomponent.NoseCone;
 import net.sf.openrocket.rocketcomponent.Stage;
 import net.sf.openrocket.rocketcomponent.Transition;
-import net.sf.openrocket.rocketcomponent.ExternalComponent;
-import net.sf.openrocket.aerodynamics.WarningSet;
-import net.sf.openrocket.database.Databases;
 
 import java.util.HashMap;
 
@@ -72,7 +71,7 @@ public class NoseConeHandlerTest extends RocksimTestBase {
     public void testConstructor() throws Exception {
 
         try {
-            new NoseConeHandler(null);
+            new NoseConeHandler(null, new WarningSet());
             fail("Should have thrown IllegalArgumentException");
         }
         catch (IllegalArgumentException iae) {
@@ -80,7 +79,7 @@ public class NoseConeHandlerTest extends RocksimTestBase {
         }
 
         Stage stage = new Stage();
-        NoseConeHandler handler = new NoseConeHandler(stage);
+        NoseConeHandler handler = new NoseConeHandler(stage, new WarningSet());
         NoseCone component = (NoseCone) getField(handler, "noseCone");
         assertContains(component, stage.getChildren());
     }
@@ -91,8 +90,8 @@ public class NoseConeHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testOpenElement() throws Exception {
-        assertEquals(PlainTextHandler.INSTANCE, new NoseConeHandler(new Stage()).openElement(null, null, null));
-        assertNotNull(new NoseConeHandler(new Stage()).openElement("AttachedParts", null, null));
+        assertEquals(PlainTextHandler.INSTANCE, new NoseConeHandler(new Stage(), new WarningSet()).openElement(null, null, null));
+        assertNotNull(new NoseConeHandler(new Stage(), new WarningSet()).openElement("AttachedParts", null, null));
     }
 
     /**
@@ -107,7 +106,7 @@ public class NoseConeHandlerTest extends RocksimTestBase {
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
 
-        NoseConeHandler handler = new NoseConeHandler(stage);
+        NoseConeHandler handler = new NoseConeHandler(stage, warnings);
         NoseCone component = (NoseCone) getField(handler, "noseCone");
 
         handler.closeElement("ShapeCode", attributes, "0", warnings);
@@ -225,7 +224,7 @@ public class NoseConeHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetComponent() throws Exception {
-        assertTrue(new NoseConeHandler(new Stage()).getComponent() instanceof NoseCone);
+        assertTrue(new NoseConeHandler(new Stage(), new WarningSet()).getComponent() instanceof NoseCone);
     }
 
     /**
@@ -234,6 +233,6 @@ public class NoseConeHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetMaterialType() throws Exception {
-        assertEquals(Material.Type.BULK, new NoseConeHandler(new Stage()).getMaterialType());
+        assertEquals(Material.Type.BULK, new NoseConeHandler(new Stage(), new WarningSet()).getMaterialType());
     }
 }
index f71461f84cb2d305ec6fd85ca6901250bfe63fd8..ae9ca2aa74a9f57c58e4b1e029d906d8c392b68a 100644 (file)
@@ -6,7 +6,6 @@ package net.sf.openrocket.file.rocksim;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import net.sf.openrocket.aerodynamics.WarningSet;
-import net.sf.openrocket.database.Databases;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.BodyTube;
@@ -68,7 +67,7 @@ public class ParachuteHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testOpenElement() throws Exception {
-        assertEquals(PlainTextHandler.INSTANCE, new ParachuteHandler(new BodyTube()).openElement(null, null, null));
+        assertEquals(PlainTextHandler.INSTANCE, new ParachuteHandler(new BodyTube(), new WarningSet()).openElement(null, null, null));
     }
 
     /**
@@ -79,7 +78,7 @@ public class ParachuteHandlerTest extends RocksimTestBase {
     public void testCloseElement() throws Exception {
 
         BodyTube tube = new BodyTube();
-        ParachuteHandler handler = new ParachuteHandler(tube);
+        ParachuteHandler handler = new ParachuteHandler(tube, new WarningSet());
         Parachute component = (Parachute) getField(handler, "chute");
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
@@ -129,7 +128,7 @@ public class ParachuteHandlerTest extends RocksimTestBase {
     public void testConstructor() throws Exception {
 
         try {
-            new ParachuteHandler(null);
+            new ParachuteHandler(null, new WarningSet());
             fail("Should have thrown IllegalArgumentException");
         }
         catch (IllegalArgumentException iae) {
@@ -137,7 +136,7 @@ public class ParachuteHandlerTest extends RocksimTestBase {
         }
 
         BodyTube tube = new BodyTube();
-        ParachuteHandler handler = new ParachuteHandler(tube);
+        ParachuteHandler handler = new ParachuteHandler(tube, new WarningSet());
         Parachute component = (Parachute) getField(handler, "chute");
         assertContains(component, tube.getChildren());
     }
@@ -149,7 +148,7 @@ public class ParachuteHandlerTest extends RocksimTestBase {
      */
     public void testSetRelativePosition() throws Exception {
         BodyTube tube = new BodyTube();
-        ParachuteHandler handler = new ParachuteHandler(tube);
+        ParachuteHandler handler = new ParachuteHandler(tube, new WarningSet());
         Parachute component = (Parachute) getField(handler, "chute");
         handler.setRelativePosition(RocketComponent.Position.ABSOLUTE);
         assertEquals(RocketComponent.Position.ABSOLUTE, component.getRelativePosition());
@@ -161,7 +160,7 @@ public class ParachuteHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetComponent() throws Exception {
-        assertTrue(new ParachuteHandler(new BodyTube()).getComponent() instanceof Parachute);
+        assertTrue(new ParachuteHandler(new BodyTube(), new WarningSet()).getComponent() instanceof Parachute);
     }
 
     /**
@@ -170,7 +169,7 @@ public class ParachuteHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetMaterialType() throws Exception {
-        assertEquals(Material.Type.SURFACE, new ParachuteHandler(new BodyTube()).getMaterialType());
+        assertEquals(Material.Type.SURFACE, new ParachuteHandler(new BodyTube(), new WarningSet()).getMaterialType());
     }
 
     /**
@@ -180,7 +179,7 @@ public class ParachuteHandlerTest extends RocksimTestBase {
      */
     public void testEndHandler() throws Exception {
         BodyTube tube = new BodyTube();
-        ParachuteHandler handler = new ParachuteHandler(tube);
+        ParachuteHandler handler = new ParachuteHandler(tube, new WarningSet());
         Parachute component = (Parachute) getField(handler, "chute");
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
diff --git a/test/net/sf/openrocket/file/rocksim/PodFins.rkt b/test/net/sf/openrocket/file/rocksim/PodFins.rkt
new file mode 100644 (file)
index 0000000..a137008
--- /dev/null
@@ -0,0 +1,605 @@
+<RockSimDocument>
+  <FileVersion>4</FileVersion>
+  <DesignInformation>
+    <RocketDesign>
+      <CalculateCD>1</CalculateCD>
+      <ProCalculateCD>1</ProCalculateCD>
+      <ProCalculateCN>1</ProCalculateCN>
+      <FixedCd>0.75</FixedCd>
+      <FixedCd2>0.8</FixedCd2>
+      <FixedCd3>0.81</FixedCd3>
+      <FixedCd2Alone>0.95</FixedCd2Alone>
+      <FixedCd3Alone>0.95</FixedCd3Alone>
+      <StageCount>1</StageCount>
+      <Stage3Mass>0.</Stage3Mass>
+      <Stage2Mass>0.</Stage2Mass>
+      <Stage1Mass>0.</Stage1Mass>
+      <Stage321CG>0.</Stage321CG>
+      <Stage32CG>0.</Stage32CG>
+      <Stage3CG>0.</Stage3CG>
+      <Stage2CGAlone>0.</Stage2CGAlone>
+      <Stage1CGAlone>0.</Stage1CGAlone>
+      <CPCalcFlags>1</CPCalcFlags>
+      <LaunchGuideLength>914.4</LaunchGuideLength>
+      <UseKnownMass>0</UseKnownMass>
+      <DefaultFinish>0</DefaultFinish>
+      <FinishMedium>0</FinishMedium>
+      <FinishCoatCount>1</FinishCoatCount>
+      <GlueType>0</GlueType>
+      <CPSimFlags>1</CPSimFlags>
+      <LastSerialNumber>7</LastSerialNumber>
+      <DisplayFlags>1</DisplayFlags>
+      <MetricsFlags>0</MetricsFlags>
+      <BarromanXN>0,567.719,0,0</BarromanXN>
+      <BarrowmanCNa>0,19.2193,0,0</BarrowmanCNa>
+      <RockSimXN>0,571.25,0,0</RockSimXN>
+      <RockSimCNa>0,28.2677,0,0</RockSimCNa>
+      <RockSimCNa90>0,0,0,0</RockSimCNa90>
+      <RockSimXN90>0,0,0,0</RockSimXN90>
+      <ViewType>0</ViewType>
+      <ViewStageCount>1</ViewStageCount>
+      <ViewTypeEdit>0</ViewTypeEdit>
+      <ViewStageCountEdit>1</ViewStageCountEdit>
+      <ZoomFactor>0.</ZoomFactor>
+      <ZoomFactorEdit>0.</ZoomFactorEdit>
+      <ScrollPosX>0</ScrollPosX>
+      <ScrollPosY>0</ScrollPosY>
+      <ScrollPosXEdit>0</ScrollPosXEdit>
+      <ScrollPosYEdit>0</ScrollPosYEdit>
+      <ThreeDFlags>0</ThreeDFlags>
+      <ThreeDFlagsEdit>0</ThreeDFlagsEdit>
+      <UseModelSprite>0</UseModelSprite>
+      <StaticMarginRef>0</StaticMarginRef>
+      <UserRefDiameter>0.</UserRefDiameter>
+      <SideMarkerHeight>10.</SideMarkerHeight>
+      <SideDimensionHeight>10.</SideDimensionHeight>
+      <BaseMarkerHeight>10.</BaseMarkerHeight>
+      <BaseDimensionHeight>10.</BaseDimensionHeight>
+      <ShowGlideCP>0</ShowGlideCP>
+      <ShowGridTypeSide>0</ShowGridTypeSide>
+      <ShowGridTypeBase>0</ShowGridTypeBase>
+      <GridSpacing>10.</GridSpacing>
+      <GridOpacity>0.15</GridOpacity>
+      <GridColor>black</GridColor>
+      <MaxDiaWithFins>259.588</MaxDiaWithFins>
+      <MaxDiaWithoutFins>56.388</MaxDiaWithoutFins>
+      <MaxLenWithFins>717.499</MaxLenWithFins>
+      <MaxLenWithoutFins>717.499</MaxLenWithoutFins>
+      <MinXExtent>0.</MinXExtent>
+      <MaxXExtent>717.499</MaxXExtent>
+      <CalculatedMaxStageDia>0,56.388,0,0</CalculatedMaxStageDia>
+      <CalculatedStageLen>0,717.499,0,0</CalculatedStageLen>
+      <Cd3>
+        <PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+        <X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+        <A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+        <B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+        <C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+      </PolyData>
+    </Cd3>
+    <Cd32>
+      <PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+      <X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+      <A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+      <B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+      <C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+    </PolyData>
+  </Cd32>
+  <Cd321>
+    <PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+    <X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+    <A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+    <B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+    <C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+  </PolyData>
+</Cd321>
+<Cb3>
+  <PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+  <X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+  <A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+  <B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+  <C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+</PolyData>
+</Cb3>
+<Cb32>
+<PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+<X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+<A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+<B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+<C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+</PolyData>
+</Cb32>
+<Cb321>
+<PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+<X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+<A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+<B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+<C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+</PolyData>
+</Cb321>
+<CNa3>
+<PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+<X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+<A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+<B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+<C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+</PolyData>
+</CNa3>
+<CNa32>
+<PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+<X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+<A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+<B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+<C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+</PolyData>
+</CNa32>
+<CNa321>
+<PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+<X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+<A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+<B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+<C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+</PolyData>
+</CNa321>
+<CP3>
+<PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+<X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+<A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+<B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+<C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+</PolyData>
+</CP3>
+<CP32>
+<PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+<X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+<A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+<B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+<C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+</PolyData>
+</CP32>
+<CP321>
+<PolyData  useXYOnly="0" useSmoothCurveEvaluation="0" count="0">
+<X-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</X-data>
+<A-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</A-data>
+<B-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</B-data>
+<C-data>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</C-data>
+</PolyData>
+</CP321>
+<SimulationEventList>
+</SimulationEventList>
+<Stage3Parts>
+<NoseCone>
+<PartMfg>Apogee</PartMfg>
+<KnownMass>24.0999</KnownMass>
+<Density>1049.21</Density>
+<Material>Polystyrene PS</Material>
+<Name>Nose cone</Name>
+<KnownCG>65.3999</KnownCG>
+<UseKnownCG>1</UseKnownCG>
+<Xb>0.</Xb>
+<CalcMass>94.7384</CalcMass>
+<CalcCG>208.434</CalcCG>
+<WettedSurface>0.0323955</WettedSurface>
+<PaintedSurface>0.0323955</PaintedSurface>
+<GlueJointLength>0.</GlueJointLength>
+<DensityType>0</DensityType>
+<PartNo>19470</PartNo>
+<PartDesc>PNC-70A</PartDesc>
+<RadialLoc>0.</RadialLoc>
+<RadialAngle>0.</RadialAngle>
+<Texture>file=()|position=(0,0,0)|origin=(0.5,0.5,0.5)|scale=(1,1,1)|repeat=(1)|interpolate=(0)|flipr(0)|flips(0)|flipt=(0)|preventseam=(1)</Texture>
+<Opacity>1.</Opacity>
+<Specular>0.</Specular>
+<SpecularPower>1.</SpecularPower>
+<Ambient>0.</Ambient>
+<Diffuse>1.</Diffuse>
+<AbientColor>blue</AbientColor>
+<DiffuseColor>blue</DiffuseColor>
+<SpecularColor>white</SpecularColor>
+<UseSingleColor>1</UseSingleColor>
+<SerialNo>1</SerialNo>
+<DisplayFlags>0</DisplayFlags>
+<MetricsFlags>0</MetricsFlags>
+<LocationMode>0</LocationMode>
+<Color>blue</Color>
+<BarrowmanCNa>2.</BarrowmanCNa>
+<BarrowmanXN>0.126958</BarrowmanXN>
+<RockSimCNa>2.</RockSimCNa>
+<RockSimXN>0.126958</RockSimXN>
+<SimpleColorModel>1</SimpleColorModel>
+<ProduceTemplate>0</ProduceTemplate>
+<TemplateUnits>8</TemplateUnits>
+<Removed>0</Removed>
+<Station>0.</Station>
+<Len>272.999</Len>
+<BaseDia>56.2991</BaseDia>
+<FinishCode>0</FinishCode>
+<ShapeCode>1</ShapeCode>
+<ConstructionType>1</ConstructionType>
+<ShoulderLen>58.3997</ShoulderLen>
+<WallThickness>2.159</WallThickness>
+<ShapeParameter>0.</ShapeParameter>
+<ShoulderOD>53.1012</ShoulderOD>
+<BaseExtensionLen>0.</BaseExtensionLen>
+<CoreDia>0.</CoreDia>
+<CoreLen>0.</CoreLen>
+<AttachedParts>
+</AttachedParts>
+</NoseCone>
+<BodyTube>
+<PartMfg>Estes</PartMfg>
+<KnownMass>0.</KnownMass>
+<Density>1121.29</Density>
+<Material>Paper</Material>
+<Name>Body tube</Name>
+<KnownCG>0.</KnownCG>
+<UseKnownCG>0</UseKnownCG>
+<Xb>0.</Xb>
+<CalcMass>44.4492</CalcMass>
+<CalcCG>222.25</CalcCG>
+<WettedSurface>0.0787423</WettedSurface>
+<PaintedSurface>0.0787423</PaintedSurface>
+<GlueJointLength>0.</GlueJointLength>
+<DensityType>0</DensityType>
+<PartNo>Estes</PartNo>
+<PartDesc>BT-70</PartDesc>
+<RadialLoc>0.</RadialLoc>
+<RadialAngle>0.</RadialAngle>
+<Texture>file=()|position=(0,0,0)|origin=(0.5,0.5,0.5)|scale=(1,1,1)|repeat=(1)|interpolate=(0)|flipr(0)|flips(0)|flipt=(0)|preventseam=(1)</Texture>
+<Opacity>1.</Opacity>
+<Specular>0.</Specular>
+<SpecularPower>1.</SpecularPower>
+<Ambient>0.</Ambient>
+<Diffuse>1.</Diffuse>
+<AbientColor>blue</AbientColor>
+<DiffuseColor>blue</DiffuseColor>
+<SpecularColor>white</SpecularColor>
+<UseSingleColor>1</UseSingleColor>
+<SerialNo>2</SerialNo>
+<DisplayFlags>1</DisplayFlags>
+<MetricsFlags>0</MetricsFlags>
+<LocationMode>0</LocationMode>
+<Color>blue</Color>
+<BarrowmanCNa>0.</BarrowmanCNa>
+<BarrowmanXN>0.</BarrowmanXN>
+<RockSimCNa>0.</RockSimCNa>
+<RockSimXN>0.</RockSimXN>
+<SimpleColorModel>1</SimpleColorModel>
+<ProduceTemplate>0</ProduceTemplate>
+<TemplateUnits>8</TemplateUnits>
+<Removed>0</Removed>
+<Station>272.999</Station>
+<OD>56.388</OD>
+<ID>55.372</ID>
+<Len>444.5</Len>
+<FinishCode>0</FinishCode>
+<IsMotorMount>0</IsMotorMount>
+<MotorDia>0.</MotorDia>
+<EngineOverhang>0.5</EngineOverhang>
+<FrontExtension>0.</FrontExtension>
+<RearExtension>0.</RearExtension>
+<IsInsideTube>0</IsInsideTube>
+<isStrapOnTube>0</isStrapOnTube>
+<AttachedParts>
+<FinSet>
+<PartMfg>Public Missiles</PartMfg>
+<KnownMass>0.</KnownMass>
+<Density>1905.24</Density>
+<Material>G10 fiberglass</Material>
+<Name>Fin set</Name>
+<KnownCG>0.</KnownCG>
+<UseKnownCG>0</UseKnownCG>
+<Xb>273.05</Xb>
+<CalcMass>75.5033</CalcMass>
+<CalcCG>110.067</CalcCG>
+<WettedSurface>0.0167742</WettedSurface>
+<PaintedSurface>0.0503225</PaintedSurface>
+<GlueJointLength>0.</GlueJointLength>
+<DensityType>0</DensityType>
+<PartNo>FIN-A-04</PartNo>
+<PartDesc>Fins</PartDesc>
+<RadialLoc>0.</RadialLoc>
+<RadialAngle>0.</RadialAngle>
+<Texture>file=()|position=(0,0,0)|origin=(0.5,0.5,0.5)|scale=(1,1,1)|repeat=(1)|interpolate=(0)|flipr(0)|flips(0)|flipt=(0)|preventseam=(1)</Texture>
+<Opacity>1.</Opacity>
+<Specular>0.</Specular>
+<SpecularPower>1.</SpecularPower>
+<Ambient>0.</Ambient>
+<Diffuse>1.</Diffuse>
+<AbientColor>blue</AbientColor>
+<DiffuseColor>blue</DiffuseColor>
+<SpecularColor>white</SpecularColor>
+<UseSingleColor>1</UseSingleColor>
+<SerialNo>4</SerialNo>
+<DisplayFlags>0</DisplayFlags>
+<MetricsFlags>0</MetricsFlags>
+<LocationMode>0</LocationMode>
+<Color>blue</Color>
+<BarrowmanCNa>16.5474</BarrowmanCNa>
+<BarrowmanXN>0.628599</BarrowmanXN>
+<RockSimCNa>23.7789</RockSimCNa>
+<RockSimXN>0.628599</RockSimXN>
+<SimpleColorModel>1</SimpleColorModel>
+<ProduceTemplate>0</ProduceTemplate>
+<TemplateUnits>8</TemplateUnits>
+<Removed>0</Removed>
+<Station>546.049</Station>
+<FinCount>3</FinCount>
+<RootChord>165.1</RootChord>
+<TipChord>0.</TipChord>
+<SemiSpan>101.6</SemiSpan>
+<MidChordLen>130.909</MidChordLen>
+<SweepDistance>165.1</SweepDistance>
+<Thickness>1.5748</Thickness>
+<ShapeCode>0</ShapeCode>
+<FinishCode>0</FinishCode>
+<TipShapeCode>1</TipShapeCode>
+<TabLength>0.</TabLength>
+<TabDepth>0.</TabDepth>
+<TabOffset>0.</TabOffset>
+<SweepMode>1</SweepMode>
+<SweepAngle>1.02001</SweepAngle>
+<RockSimXNPerFin>0.</RockSimXNPerFin>
+<RockSimRadialXNPerFin>62.0607</RockSimRadialXNPerFin>
+<RockSimCNaPerFin>13.7288</RockSimCNaPerFin>
+<TaperRatio>0.</TaperRatio>
+<CantAngle>0.</CantAngle>
+<CantPivotPoint>0.</CantPivotPoint>
+<AttachedParts>
+</AttachedParts>
+</FinSet>
+<BodyTube>
+<PartMfg>Apogee</PartMfg>
+<KnownMass>0.</KnownMass>
+<Density>1121.29</Density>
+<Material>Paper</Material>
+<Name>Body tube</Name>
+<KnownCG>0.</KnownCG>
+<UseKnownCG>0</UseKnownCG>
+<Xb>107.95</Xb>
+<CalcMass>1.7435</CalcMass>
+<CalcCG>55.5625</CalcCG>
+<WettedSurface>0.</WettedSurface>
+<PaintedSurface>0.</PaintedSurface>
+<GlueJointLength>0.</GlueJointLength>
+<DensityType>0</DensityType>
+<PartNo>10062</PartNo>
+<PartDesc>13 mm</PartDesc>
+<RadialLoc>0.</RadialLoc>
+<RadialAngle>0.</RadialAngle>
+<Texture>file=()|position=(0,0,0)|origin=(0.5,0.5,0.5)|scale=(1,1,1)|repeat=(1)|interpolate=(0)|flipr(0)|flips(0)|flipt=(0)|preventseam=(1)</Texture>
+<Opacity>1.</Opacity>
+<Specular>0.</Specular>
+<SpecularPower>1.</SpecularPower>
+<Ambient>0.</Ambient>
+<Diffuse>1.</Diffuse>
+<AbientColor>blue</AbientColor>
+<DiffuseColor>blue</DiffuseColor>
+<SpecularColor>white</SpecularColor>
+<UseSingleColor>1</UseSingleColor>
+<SerialNo>5</SerialNo>
+<DisplayFlags>0</DisplayFlags>
+<MetricsFlags>0</MetricsFlags>
+<LocationMode>0</LocationMode>
+<Color>blue</Color>
+<BarrowmanCNa>0.</BarrowmanCNa>
+<BarrowmanXN>0.</BarrowmanXN>
+<RockSimCNa>0.</RockSimCNa>
+<RockSimXN>0.</RockSimXN>
+<SimpleColorModel>1</SimpleColorModel>
+<ProduceTemplate>0</ProduceTemplate>
+<TemplateUnits>8</TemplateUnits>
+<Removed>0</Removed>
+<Station>380.949</Station>
+<OD>13.8176</OD>
+<ID>13.1572</ID>
+<Len>111.125</Len>
+<FinishCode>0</FinishCode>
+<IsMotorMount>0</IsMotorMount>
+<MotorDia>13.</MotorDia>
+<EngineOverhang>0.5</EngineOverhang>
+<FrontExtension>0.</FrontExtension>
+<RearExtension>0.</RearExtension>
+<IsInsideTube>1</IsInsideTube>
+<isStrapOnTube>0</isStrapOnTube>
+<AttachedParts>
+<FinSet>
+<PartMfg>Public Missiles</PartMfg>
+<KnownMass>0.</KnownMass>
+<Density>1905.24</Density>
+<Material>G10 fiberglass</Material>
+<Name>Fin set</Name>
+<KnownCG>0.</KnownCG>
+<UseKnownCG>0</UseKnownCG>
+<Xb>0.</Xb>
+<CalcMass>5.53666</CalcMass>
+<CalcCG>44.5707</CalcCG>
+<WettedSurface>0.00365927</WettedSurface>
+<PaintedSurface>0.00365927</PaintedSurface>
+<GlueJointLength>0.</GlueJointLength>
+<DensityType>0</DensityType>
+<PartNo>FIN-A-06</PartNo>
+<PartDesc>Fins</PartDesc>
+<RadialLoc>0.</RadialLoc>
+<RadialAngle>0.</RadialAngle>
+<Texture>file=()|position=(0,0,0)|origin=(0.5,0.5,0.5)|scale=(1,1,1)|repeat=(1)|interpolate=(0)|flipr(0)|flips(0)|flipt=(0)|preventseam=(1)</Texture>
+<Opacity>1.</Opacity>
+<Specular>0.</Specular>
+<SpecularPower>1.</SpecularPower>
+<Ambient>0.</Ambient>
+<Diffuse>1.</Diffuse>
+<AbientColor>blue</AbientColor>
+<DiffuseColor>blue</DiffuseColor>
+<SpecularColor>white</SpecularColor>
+<UseSingleColor>1</UseSingleColor>
+<SerialNo>7</SerialNo>
+<DisplayFlags>0</DisplayFlags>
+<MetricsFlags>0</MetricsFlags>
+<LocationMode>0</LocationMode>
+<Color>blue</Color>
+<BarrowmanCNa>0.671866</BarrowmanCNa>
+<BarrowmanXN>0.380349</BarrowmanXN>
+<RockSimCNa>2.4888</RockSimCNa>
+<RockSimXN>0.380349</RockSimXN>
+<SimpleColorModel>1</SimpleColorModel>
+<ProduceTemplate>0</ProduceTemplate>
+<TemplateUnits>8</TemplateUnits>
+<Removed>0</Removed>
+<Station>349.199</Station>
+<FinCount>1</FinCount>
+<RootChord>66.675</RootChord>
+<TipChord>38.1</TipChord>
+<SemiSpan>34.925</SemiSpan>
+<MidChordLen>42.7843</MidChordLen>
+<SweepDistance>39.0017</SweepDistance>
+<Thickness>1.5875</Thickness>
+<ShapeCode>0</ShapeCode>
+<FinishCode>0</FinishCode>
+<TipShapeCode>0</TipShapeCode>
+<TabLength>0.</TabLength>
+<TabDepth>0.</TabDepth>
+<TabOffset>0.</TabOffset>
+<SweepMode>1</SweepMode>
+<SweepAngle>0.366519</SweepAngle>
+<RockSimXNPerFin>0.</RockSimXNPerFin>
+<RockSimRadialXNPerFin>44.069</RockSimRadialXNPerFin>
+<RockSimCNaPerFin>2.87382</RockSimCNaPerFin>
+<TaperRatio>0.571429</TaperRatio>
+<CantAngle>0.</CantAngle>
+<CantPivotPoint>0.</CantPivotPoint>
+<AttachedParts>
+</AttachedParts>
+</FinSet>
+</AttachedParts>
+</BodyTube>
+<ExternalPod>
+<PartMfg>Custom</PartMfg>
+<KnownMass>0.</KnownMass>
+<Density>0.</Density>
+<Name>Pod</Name>
+<KnownCG>0.</KnownCG>
+<UseKnownCG>0</UseKnownCG>
+<Xb>76.2</Xb>
+<CalcMass>0.</CalcMass>
+<CalcCG>0.</CalcCG>
+<WettedSurface>0.</WettedSurface>
+<PaintedSurface>0.</PaintedSurface>
+<GlueJointLength>0.</GlueJointLength>
+<DensityType>0</DensityType>
+<RadialLoc>28.194</RadialLoc>
+<RadialAngle>0.</RadialAngle>
+<Texture>file=()|position=(0,0,0)|origin=(0.5,0.5,0.5)|scale=(1,1,1)|repeat=(1)|interpolate=(0)|flipr(0)|flips(0)|flipt=(0)|preventseam=(1)</Texture>
+<Opacity>1.</Opacity>
+<Specular>0.</Specular>
+<SpecularPower>1.</SpecularPower>
+<Ambient>0.</Ambient>
+<Diffuse>1.</Diffuse>
+<AbientColor>blue</AbientColor>
+<DiffuseColor>blue</DiffuseColor>
+<SpecularColor>white</SpecularColor>
+<UseSingleColor>1</UseSingleColor>
+<SerialNo>6</SerialNo>
+<DisplayFlags>1</DisplayFlags>
+<MetricsFlags>0</MetricsFlags>
+<LocationMode>0</LocationMode>
+<Color>blue</Color>
+<BarrowmanCNa>0.</BarrowmanCNa>
+<BarrowmanXN>0.</BarrowmanXN>
+<RockSimCNa>0.</RockSimCNa>
+<RockSimXN>0.</RockSimXN>
+<SimpleColorModel>1</SimpleColorModel>
+<ProduceTemplate>0</ProduceTemplate>
+<TemplateUnits>8</TemplateUnits>
+<Removed>0</Removed>
+<Station>349.199</Station>
+<Detachable>1</Detachable>
+<AutoCalcRadialDistance>1</AutoCalcRadialDistance>
+<AutoCalcRadialAngle>1</AutoCalcRadialAngle>
+<AttachedParts>
+<FinSet>
+<PartMfg>Public Missiles</PartMfg>
+<KnownMass>0.</KnownMass>
+<Density>1905.24</Density>
+<Material>G10 fiberglass</Material>
+<Name>Fin set</Name>
+<KnownCG>0.</KnownCG>
+<UseKnownCG>0</UseKnownCG>
+<Xb>0.</Xb>
+<CalcMass>5.53666</CalcMass>
+<CalcCG>44.5707</CalcCG>
+<WettedSurface>0.00365927</WettedSurface>
+<PaintedSurface>0.00365927</PaintedSurface>
+<GlueJointLength>0.</GlueJointLength>
+<DensityType>0</DensityType>
+<PartNo>FIN-A-06</PartNo>
+<PartDesc>Fins</PartDesc>
+<RadialLoc>0.</RadialLoc>
+<RadialAngle>0.</RadialAngle>
+<Texture>file=()|position=(0,0,0)|origin=(0.5,0.5,0.5)|scale=(1,1,1)|repeat=(1)|interpolate=(0)|flipr(0)|flips(0)|flipt=(0)|preventseam=(1)</Texture>
+<Opacity>1.</Opacity>
+<Specular>0.</Specular>
+<SpecularPower>1.</SpecularPower>
+<Ambient>0.</Ambient>
+<Diffuse>1.</Diffuse>
+<AbientColor>blue</AbientColor>
+<DiffuseColor>blue</DiffuseColor>
+<SpecularColor>white</SpecularColor>
+<UseSingleColor>1</UseSingleColor>
+<SerialNo>7</SerialNo>
+<DisplayFlags>0</DisplayFlags>
+<MetricsFlags>0</MetricsFlags>
+<LocationMode>0</LocationMode>
+<Color>blue</Color>
+<BarrowmanCNa>0.671866</BarrowmanCNa>
+<BarrowmanXN>0.380349</BarrowmanXN>
+<RockSimCNa>2.4888</RockSimCNa>
+<RockSimXN>0.380349</RockSimXN>
+<SimpleColorModel>1</SimpleColorModel>
+<ProduceTemplate>0</ProduceTemplate>
+<TemplateUnits>8</TemplateUnits>
+<Removed>0</Removed>
+<Station>349.199</Station>
+<FinCount>1</FinCount>
+<RootChord>66.675</RootChord>
+<TipChord>38.1</TipChord>
+<SemiSpan>34.925</SemiSpan>
+<MidChordLen>42.7843</MidChordLen>
+<SweepDistance>39.0017</SweepDistance>
+<Thickness>1.5875</Thickness>
+<ShapeCode>0</ShapeCode>
+<FinishCode>0</FinishCode>
+<TipShapeCode>0</TipShapeCode>
+<TabLength>0.</TabLength>
+<TabDepth>0.</TabDepth>
+<TabOffset>0.</TabOffset>
+<SweepMode>1</SweepMode>
+<SweepAngle>0.366519</SweepAngle>
+<RockSimXNPerFin>0.</RockSimXNPerFin>
+<RockSimRadialXNPerFin>44.069</RockSimRadialXNPerFin>
+<RockSimCNaPerFin>2.87382</RockSimCNaPerFin>
+<TaperRatio>0.571429</TaperRatio>
+<CantAngle>0.</CantAngle>
+<CantPivotPoint>0.</CantPivotPoint>
+<AttachedParts>
+</AttachedParts>
+</FinSet>
+</AttachedParts>
+</ExternalPod>
+</AttachedParts>
+</BodyTube>
+</Stage3Parts>
+<Stage2Parts>
+</Stage2Parts>
+<Stage1Parts>
+</Stage1Parts>
+<SideViewDims>
+</SideViewDims>
+<BaseViewDims>
+</BaseViewDims>
+<VertViewDims>
+</VertViewDims>
+</RocketDesign>
+</DesignInformation>
+<SimulationResultsList>
+</SimulationResultsList>
+</RockSimDocument>
index 5495d56022dee3c1fdb10f0ab1e023bd51ddfeaf..e96355a989c77e133dd804fdf77e34b265d52ee8 100644 (file)
@@ -6,7 +6,6 @@ package net.sf.openrocket.file.rocksim;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import net.sf.openrocket.aerodynamics.WarningSet;
-import net.sf.openrocket.database.Databases;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.BodyTube;
@@ -68,7 +67,7 @@ public class RingHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testOpenElement() throws Exception {
-        assertEquals(PlainTextHandler.INSTANCE, new RingHandler(new BodyTube()).openElement(null, null, null));
+        assertEquals(PlainTextHandler.INSTANCE, new RingHandler(new BodyTube(), new WarningSet()).openElement(null, null, null));
     }
 
     /**
@@ -79,7 +78,7 @@ public class RingHandlerTest extends RocksimTestBase {
     public void testCloseElement() throws Exception {
 
         BodyTube tube = new BodyTube();
-        RingHandler handler = new RingHandler(tube);
+        RingHandler handler = new RingHandler(tube, new WarningSet());
         CenteringRing component = (CenteringRing) getField(handler, "ring");
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
@@ -123,7 +122,7 @@ public class RingHandlerTest extends RocksimTestBase {
     public void testConstructor() throws Exception {
 
         try {
-            new RingHandler(null);
+            new RingHandler(null, new WarningSet());
             fail("Should have thrown IllegalArgumentException");
         }
         catch (IllegalArgumentException iae) {
@@ -131,7 +130,7 @@ public class RingHandlerTest extends RocksimTestBase {
         }
 
         BodyTube tube = new BodyTube();
-        RingHandler handler = new RingHandler(tube);
+        RingHandler handler = new RingHandler(tube, new WarningSet());
         CenteringRing component = (CenteringRing) getField(handler, "ring");
         assertContains(component, tube.getChildren());
     }
@@ -143,7 +142,7 @@ public class RingHandlerTest extends RocksimTestBase {
      */
     public void testSetRelativePosition() throws Exception {
         BodyTube tube = new BodyTube();
-        RingHandler handler = new RingHandler(tube);
+        RingHandler handler = new RingHandler(tube, new WarningSet());
         CenteringRing component = (CenteringRing) getField(handler, "ring");
         handler.setRelativePosition(RocketComponent.Position.ABSOLUTE);
         assertEquals(RocketComponent.Position.ABSOLUTE, component.getRelativePosition());
@@ -155,7 +154,7 @@ public class RingHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetComponent() throws Exception {
-        assertTrue(new RingHandler(new BodyTube()).getComponent() instanceof CenteringRing);
+        assertTrue(new RingHandler(new BodyTube(), new WarningSet()).getComponent() instanceof CenteringRing);
     }
 
     /**
@@ -164,7 +163,7 @@ public class RingHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetMaterialType() throws Exception {
-        assertEquals(Material.Type.BULK, new RingHandler(new BodyTube()).getMaterialType());
+        assertEquals(Material.Type.BULK, new RingHandler(new BodyTube(), new WarningSet()).getMaterialType());
     }
 
 
index 45551aea5c793a6483ce991728a71ea0fc2bb38b..9b33319d5aff4412ce1adf70ec56c7630557d48e 100644 (file)
@@ -4,9 +4,6 @@
  */
 package net.sf.openrocket.file.rocksim;
 
-import java.io.BufferedInputStream;
-import java.io.InputStream;
-
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
@@ -14,6 +11,9 @@ import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.rocketcomponent.Rocket;
 import net.sf.openrocket.rocketcomponent.Stage;
 
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+
 /**
  * RocksimLoader Tester.
  *
@@ -62,6 +62,27 @@ public class RocksimLoaderTest extends TestCase {
         super.tearDown();
     }
 
+    /**
+     * Test a bug reported via automated bug report.  I have been unable to reproduce this bug
+     * (hanging finset off of an inner body tube) when creating a Rocksim file using Rocksim.  The bug
+     * is reproducible when manually modifying the Rocksim file, which is what is tested here.
+     */
+    public void testFinsOnInnerTube() throws Exception {
+        RocksimLoader loader = new RocksimLoader();
+        InputStream stream = this.getClass().getResourceAsStream("PodFins.rkt");
+        assertNotNull("Could not open PodFins.rkt", stream);
+        try {
+            OpenRocketDocument doc = loader.loadFromStream(new BufferedInputStream(stream));
+            assertNotNull(doc);
+            Rocket rocket = doc.getRocket();
+            assertNotNull(rocket);
+        }
+        catch (IllegalStateException ise) {
+            fail(ise.getMessage());            
+        }
+        assertTrue(loader.getWarnings().size() == 2);
+    }
+
     /**
      *
      * Method: loadFromStream(InputStream source)
index 3051398d1d417c19b1223ec8f496a161c222476a..092f5d09e2c9d2cf967d9f88490d6ffbef95be6b 100644 (file)
@@ -67,7 +67,7 @@ public class StreamerHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testOpenElement() throws Exception {
-        assertEquals(PlainTextHandler.INSTANCE, new StreamerHandler(new BodyTube()).openElement(null, null, null));
+        assertEquals(PlainTextHandler.INSTANCE, new StreamerHandler(new BodyTube(), new WarningSet()).openElement(null, null, null));
     }
 
     /**
@@ -78,7 +78,7 @@ public class StreamerHandlerTest extends RocksimTestBase {
     public void testCloseElement() throws Exception {
 
         BodyTube tube = new BodyTube();
-        StreamerHandler handler = new StreamerHandler(tube);
+        StreamerHandler handler = new StreamerHandler(tube, new WarningSet());
         Streamer component = (Streamer) getField(handler, "streamer");
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
@@ -122,7 +122,7 @@ public class StreamerHandlerTest extends RocksimTestBase {
     public void testConstructor() throws Exception {
 
         try {
-            new StreamerHandler(null);
+            new StreamerHandler(null, new WarningSet());
             fail("Should have thrown IllegalArgumentException");
         }
         catch (IllegalArgumentException iae) {
@@ -130,7 +130,7 @@ public class StreamerHandlerTest extends RocksimTestBase {
         }
 
         BodyTube tube = new BodyTube();
-        StreamerHandler handler = new StreamerHandler(tube);
+        StreamerHandler handler = new StreamerHandler(tube, new WarningSet());
         Streamer component = (Streamer) getField(handler, "streamer");
         assertContains(component, tube.getChildren());
     }
@@ -142,7 +142,7 @@ public class StreamerHandlerTest extends RocksimTestBase {
      */
     public void testSetRelativePosition() throws Exception {
         BodyTube tube = new BodyTube();
-        StreamerHandler handler = new StreamerHandler(tube);
+        StreamerHandler handler = new StreamerHandler(tube, new WarningSet());
         Streamer component = (Streamer) getField(handler, "streamer");
         handler.setRelativePosition(RocketComponent.Position.ABSOLUTE);
         assertEquals(RocketComponent.Position.ABSOLUTE, component.getRelativePosition());
@@ -154,7 +154,7 @@ public class StreamerHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetComponent() throws Exception {
-        assertTrue(new StreamerHandler(new BodyTube()).getComponent() instanceof Streamer);
+        assertTrue(new StreamerHandler(new BodyTube(), new WarningSet()).getComponent() instanceof Streamer);
     }
 
     /**
@@ -163,7 +163,7 @@ public class StreamerHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetMaterialType() throws Exception {
-        assertEquals(Material.Type.SURFACE, new StreamerHandler(new BodyTube()).getMaterialType());
+        assertEquals(Material.Type.SURFACE, new StreamerHandler(new BodyTube(), new WarningSet()).getMaterialType());
     }
 
     /**
@@ -173,7 +173,7 @@ public class StreamerHandlerTest extends RocksimTestBase {
      */
     public void testEndHandler() throws Exception {
         BodyTube tube = new BodyTube();
-        StreamerHandler handler = new StreamerHandler(tube);
+        StreamerHandler handler = new StreamerHandler(tube, new WarningSet());
         Streamer component = (Streamer) getField(handler, "streamer");
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
index f199f9aaf4110ba9fafa47db2b863a572d9eeb2d..d28f53f8d49cd3555b719144db1df8e72e4db687 100644 (file)
@@ -6,7 +6,6 @@ package net.sf.openrocket.file.rocksim;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import net.sf.openrocket.aerodynamics.WarningSet;
-import net.sf.openrocket.database.Databases;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.ExternalComponent;
@@ -70,7 +69,7 @@ public class TransitionHandlerTest extends RocksimTestBase {
     public void testConstructor() throws Exception {
 
         try {
-            new TransitionHandler(null);
+            new TransitionHandler(null, new WarningSet());
             fail("Should have thrown IllegalArgumentException");
         }
         catch (IllegalArgumentException iae) {
@@ -78,7 +77,7 @@ public class TransitionHandlerTest extends RocksimTestBase {
         }
 
         Stage stage = new Stage();
-        TransitionHandler handler = new TransitionHandler(stage);
+        TransitionHandler handler = new TransitionHandler(stage, new WarningSet());
         Transition component = (Transition) getField(handler, "transition");
         assertContains(component, stage.getChildren());
     }
@@ -89,7 +88,7 @@ public class TransitionHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testOpenElement() throws Exception {
-        assertEquals(PlainTextHandler.INSTANCE, new TransitionHandler(new Stage()).openElement(null, null, null));
+        assertEquals(PlainTextHandler.INSTANCE, new TransitionHandler(new Stage(), new WarningSet()).openElement(null, null, null));
     }
 
     /**
@@ -103,7 +102,7 @@ public class TransitionHandlerTest extends RocksimTestBase {
         HashMap<String, String> attributes = new HashMap<String, String>();
         WarningSet warnings = new WarningSet();
 
-        TransitionHandler handler = new TransitionHandler(stage);
+        TransitionHandler handler = new TransitionHandler(stage, new WarningSet());
         Transition component = (Transition) getField(handler, "transition");
 
         handler.closeElement("ShapeCode", attributes, "0", warnings);
@@ -252,7 +251,7 @@ public class TransitionHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetComponent() throws Exception {
-        assertTrue(new TransitionHandler(new Stage()).getComponent() instanceof Transition);
+        assertTrue(new TransitionHandler(new Stage(), new WarningSet()).getComponent() instanceof Transition);
     }
 
     /**
@@ -261,7 +260,7 @@ public class TransitionHandlerTest extends RocksimTestBase {
      * @throws Exception thrown if something goes awry
      */
     public void testGetMaterialType() throws Exception {
-        assertEquals(Material.Type.BULK, new TransitionHandler(new Stage()).getMaterialType());
+        assertEquals(Material.Type.BULK, new TransitionHandler(new Stage(), new WarningSet()).getMaterialType());
     }