From 1702a28d6273fecbab3ff5acda01d91f58973cba Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 2 Nov 2022 18:03:23 +0100 Subject: [PATCH 1/6] [#1781] Support multi-component parameter additions --- .../GeneralOptimizationDialog.java | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java index 59ce8c45a..f92b53d81 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -264,9 +265,9 @@ public class GeneralOptimizationDialog extends JDialog { addButton = new SelectColorButton(Chars.LEFT_ARROW + " " + trans.get("btn.add") + " "); addButton.setToolTipText(trans.get("btn.add.ttip")); addButton.addActionListener(e -> { - SimulationModifier mod = getSelectedAvailableModifier(); - if (mod != null) { - addModifier(mod); + List mods = getSelectedAvailableModifiers(); + if (mods.size() > 0) { + addModifiers(mods); clearHistory(); } else { log.error("Attempting to add simulation modifier when none is selected"); @@ -328,9 +329,9 @@ public class GeneralOptimizationDialog extends JDialog { @Override public void mousePressed(MouseEvent e) { if (e.getClickCount() == 2) { - SimulationModifier mod = getSelectedAvailableModifier(); - if (mod != null) { - addModifier(mod); + List mods = getSelectedAvailableModifiers(); + if (mods.size() == 1) { + addModifiers(mods); clearHistory(); } else { log.info(Markers.USER_MARKER, "Double-clicked non-available option"); @@ -1027,15 +1028,20 @@ public class GeneralOptimizationDialog extends JDialog { } - private void addModifier(SimulationModifier mod) { - if (!selectedModifiers.contains(mod)) { + private void addModifiers(List mods) { + if (mods == null || mods.size() == 0) { + return; + } + for (SimulationModifier mod : mods) { + if (selectedModifiers.contains(mod)) { + log.info(Markers.USER_MARKER, "Attempting to add an already existing simulation modifier " + mod); + continue; + } log.info(Markers.USER_MARKER, "Adding simulation modifier " + mod); selectedModifiers.add(mod); - selectedModifierTableModel.fireTableDataChanged(); - availableModifierTree.repaint(); - } else { - log.info(Markers.USER_MARKER, "Attempting to add an already existing simulation modifier " + mod); } + selectedModifierTableModel.fireTableDataChanged(); + availableModifierTree.repaint(); } private void removeModifier(SimulationModifier mod) { @@ -1069,8 +1075,8 @@ public class GeneralOptimizationDialog extends JDialog { } // "Add" button - SimulationModifier mod = getSelectedAvailableModifier(); - state = (mod != null && !selectedModifiers.contains(mod)); + List mods = getSelectedAvailableModifiers(); + state = (mods.size() > 0 && !new HashSet<>(selectedModifiers).containsAll(mods)); log.debug("addButton enabled: " + state); addButton.setEnabled(state); @@ -1122,9 +1128,9 @@ public class GeneralOptimizationDialog extends JDialog { } // Update description text - mod = getSelectedModifier(); - if (mod != null) { - selectedModifierDescription.setText(mod.getDescription()); + SimulationModifier selectedMod = getSelectedModifier(); + if (selectedMod != null) { + selectedModifierDescription.setText(selectedMod.getDescription()); } else { selectedModifierDescription.setText(""); } @@ -1221,18 +1227,20 @@ public class GeneralOptimizationDialog extends JDialog { } /** - * Return the currently selected available simulation modifier from the modifier tree, - * or null if none selected. + * Return the currently selected available simulation modifier from the modifier tree. */ - private SimulationModifier getSelectedAvailableModifier() { - TreePath treepath = availableModifierTree.getSelectionPath(); - if (treepath != null) { - Object o = ((DefaultMutableTreeNode) treepath.getLastPathComponent()).getUserObject(); - if (o instanceof SimulationModifier) { - return (SimulationModifier) o; + private List getSelectedAvailableModifiers() { + List result = new ArrayList<>(); + TreePath[] treepaths = availableModifierTree.getSelectionPaths(); + if (treepaths != null) { + for (TreePath treepath : treepaths) { + Object obj = ((DefaultMutableTreeNode) treepath.getLastPathComponent()).getUserObject(); + if (obj instanceof SimulationModifier) { + result.add((SimulationModifier) obj); + } } } - return null; + return result; } /** From 55bc26ab89c0a1c6a2cd646d1690fb59d78047be Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 2 Nov 2022 18:14:10 +0100 Subject: [PATCH 2/6] [#1781] Support multi-component parameter deletions --- .../GeneralOptimizationDialog.java | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java index f92b53d81..c963ae877 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java @@ -219,7 +219,7 @@ public class GeneralOptimizationDialog extends JDialog { selectedModifierTable.setDefaultRenderer(Double.class, new DoubleCellRenderer()); selectedModifierTable.setRowSelectionAllowed(true); selectedModifierTable.setColumnSelectionAllowed(false); - selectedModifierTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + selectedModifierTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); // Make sure spinner editor fits into the cell height selectedModifierTable.setRowHeight(new JSpinner().getPreferredSize().height - 4); @@ -282,8 +282,8 @@ public class GeneralOptimizationDialog extends JDialog { removeButton = new SelectColorButton(" " + trans.get("btn.delete") + " " + Chars.RIGHT_ARROW); removeButton.setToolTipText(trans.get("btn.delete.ttip")); removeButton.addActionListener(e -> { - SimulationModifier mod = getSelectedModifier(); - if (mod == null) { + List mods = getSelectedModifiers(); + if (mods.size() == 0) { log.error("Attempting to remove simulation modifier when none is selected"); return; } @@ -292,7 +292,7 @@ public class GeneralOptimizationDialog extends JDialog { selectedModifierTable.getCellEditor().stopCellEditing(); } - removeModifier(mod); + removeModifiers(mods); clearHistory(); }); disableComponents.add(removeButton); @@ -1044,9 +1044,14 @@ public class GeneralOptimizationDialog extends JDialog { availableModifierTree.repaint(); } - private void removeModifier(SimulationModifier mod) { - log.info(Markers.USER_MARKER, "Removing simulation modifier " + mod); - selectedModifiers.remove(mod); + private void removeModifiers(List mods) { + if (mods == null || mods.size() == 0) { + return; + } + log.info(Markers.USER_MARKER, "Removing simulation modifiers " + mods); + for (SimulationModifier mod : mods) { + selectedModifiers.remove(mod); + } selectedModifierTableModel.fireTableDataChanged(); availableModifierTree.repaint(); } @@ -1128,9 +1133,9 @@ public class GeneralOptimizationDialog extends JDialog { } // Update description text - SimulationModifier selectedMod = getSelectedModifier(); - if (selectedMod != null) { - selectedModifierDescription.setText(selectedMod.getDescription()); + List selectedMods = getSelectedModifiers(); + if (selectedMods.size() == 1) { + selectedModifierDescription.setText(selectedMods.get(0).getDescription()); } else { selectedModifierDescription.setText(""); } @@ -1265,17 +1270,17 @@ public class GeneralOptimizationDialog extends JDialog { } /** - * Return the currently selected simulation modifier from the table, - * or null if none selected. - * @return the selected modifier or null. + * Return the currently selected simulation modifiers from the table. + * @return the selected modifier. */ - private SimulationModifier getSelectedModifier() { - int row = selectedModifierTable.getSelectedRow(); - if (row < 0) { - return null; + private List getSelectedModifiers() { + List result = new ArrayList<>(); + int[] rows = selectedModifierTable.getSelectedRows(); + for (int row : rows) { + int idx = selectedModifierTable.convertRowIndexToModel(row); + result.add(selectedModifiers.get(idx)); } - row = selectedModifierTable.convertRowIndexToModel(row); - return selectedModifiers.get(row); + return result; } /** From 3d3ad2486bff5ad8e55f838494011bc74d585e11 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 3 Nov 2022 21:44:14 +0100 Subject: [PATCH 3/6] Rename SubAssembly RockSim test This is really confusing as it's not about the SubAssembly component in RockSim... --- ...AssemblyTest.rkt => BodyTubeChildrenTest.rkt} | 2 +- .../file/rocksim/importt/RockSimLoaderTest.java | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) rename core/test/net/sf/openrocket/file/rocksim/importt/{SubAssemblyTest.rkt => BodyTubeChildrenTest.rkt} (99%) diff --git a/core/test/net/sf/openrocket/file/rocksim/importt/SubAssemblyTest.rkt b/core/test/net/sf/openrocket/file/rocksim/importt/BodyTubeChildrenTest.rkt similarity index 99% rename from core/test/net/sf/openrocket/file/rocksim/importt/SubAssemblyTest.rkt rename to core/test/net/sf/openrocket/file/rocksim/importt/BodyTubeChildrenTest.rkt index 7bb84f148..a678fd281 100644 --- a/core/test/net/sf/openrocket/file/rocksim/importt/SubAssemblyTest.rkt +++ b/core/test/net/sf/openrocket/file/rocksim/importt/BodyTubeChildrenTest.rkt @@ -2,7 +2,7 @@ 4 - SubAssembly Element Test + Body Tube Children Test 1 7 0 diff --git a/core/test/net/sf/openrocket/file/rocksim/importt/RockSimLoaderTest.java b/core/test/net/sf/openrocket/file/rocksim/importt/RockSimLoaderTest.java index d4706308e..1a670d304 100644 --- a/core/test/net/sf/openrocket/file/rocksim/importt/RockSimLoaderTest.java +++ b/core/test/net/sf/openrocket/file/rocksim/importt/RockSimLoaderTest.java @@ -146,20 +146,20 @@ public class RockSimLoaderTest extends BaseTestCase { } @org.junit.Test - public void testSubAssemblyRocket() throws IOException, RocketLoadException { + public void testBodyTubeChildrenRocket() throws IOException, RocketLoadException { RockSimLoader loader = new RockSimLoader(); //Stupid single stage rocket - OpenRocketDocument doc = loadRockSimSubassemblyRocket(loader); + OpenRocketDocument doc = loadBodyTubeChildrenRocket(loader); InputStream stream; Assert.assertNotNull(doc); Rocket rocket = doc.getRocket(); Assert.assertNotNull(rocket); - Assert.assertEquals("SubAssembly Element Test", doc.getRocket().getName()); + Assert.assertEquals("Body Tube Children Test", doc.getRocket().getName()); Assert.assertTrue(loader.getWarnings().isEmpty()); - stream = this.getClass().getResourceAsStream("SubAssemblyTest.rkt"); - Assert.assertNotNull("Could not open SubAssemblyTest.rkt", stream); + stream = this.getClass().getResourceAsStream("BodyTubeChildrenTest.rkt"); + Assert.assertNotNull("Could not open BodyTubeChildrenTest.rkt", stream); doc = OpenRocketDocumentFactory.createEmptyRocket(); DocumentLoadingContext context = new DocumentLoadingContext(); @@ -220,10 +220,10 @@ public class RockSimLoaderTest extends BaseTestCase { } } - public static OpenRocketDocument loadRockSimSubassemblyRocket(RockSimLoader theLoader) throws IOException, RocketLoadException { - InputStream stream = RockSimLoaderTest.class.getResourceAsStream("SubAssemblyTest.rkt"); + public static OpenRocketDocument loadBodyTubeChildrenRocket(RockSimLoader theLoader) throws IOException, RocketLoadException { + InputStream stream = RockSimLoaderTest.class.getResourceAsStream("BodyTubeChildrenTest.rkt"); try { - Assert.assertNotNull("Could not open SubAssemblyTest.rkt", stream); + Assert.assertNotNull("Could not open BodyTubeChildrenTest.rkt", stream); OpenRocketDocument doc = OpenRocketDocumentFactory.createEmptyRocket(); DocumentLoadingContext context = new DocumentLoadingContext(); context.setOpenRocketDocument(doc); From 6f6fc1dd23993502b8337d565908932b853f4541 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 3 Nov 2022 23:58:44 +0100 Subject: [PATCH 4/6] [#1787] Deselect components when no components clicked --- .../src/net/sf/openrocket/gui/scalefigure/RocketPanel.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index 2accd4702..bda631bc3 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -609,7 +609,11 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change List selectedComponents = Arrays.stream(selectionModel.getSelectionPaths()) .map(c -> (RocketComponent) c.getLastPathComponent()).collect(Collectors.toList()); - if (clicked == null || clicked.length == 0) return; + if (clicked == null || clicked.length == 0) { + selectionModel.setSelectionPaths(null); + ComponentConfigDialog.disposeDialog(); + return; + } // Check for double-click. // If the shift/meta key is not pressed and the component was not already selected, ignore the double click and treat it as a single click From 90cceecd6506c1384eb27a0453957173d51c26ef Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 4 Nov 2022 00:38:32 +0100 Subject: [PATCH 5/6] [#106] Fix SubAssembly importing in RockSim --- .../file/rocksim/importt/RockSimHandler.java | 3 +++ .../rocksim/importt/SubAssemblyHandler.java | 20 +++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/RockSimHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/RockSimHandler.java index 52f0c8fe7..1aef79cd3 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/RockSimHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/RockSimHandler.java @@ -350,6 +350,9 @@ class StageHandler extends AbstractElementHandler { if (RockSimCommonConstants.TRANSITION.equals(element)) { return new TransitionHandler(context, component, warnings); } + if (RockSimCommonConstants.SUBASSEMBLY.equals(element)) { + return new SubAssemblyHandler(context, component); + } return null; } } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/SubAssemblyHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/SubAssemblyHandler.java index 476696a03..a80f3034d 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/SubAssemblyHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/SubAssemblyHandler.java @@ -10,18 +10,21 @@ import net.sf.openrocket.rocketcomponent.RocketComponent; import java.util.HashMap; /** - * This class handles Rocksim 'SubAssembly' elements. They are similar to 'AttachedParts' (which is why this class is subclassed from - * AttachedPartsHandler) with some key differences. In Rocksim, AttachedParts elements can contain SubAssembly elements, which can in turn + * This class handles RockSim 'SubAssembly' elements. They are similar to 'AttachedParts' (which is why this class is subclassed from + * AttachedPartsHandler) with some key differences. In RockSim, AttachedParts elements can contain SubAssembly elements, which can in turn * contain AttachedParts elements. To represent them in OR, SubAssembly elements are treated as children of the stage - much like a nose cone or * external body tube. */ public class SubAssemblyHandler extends AttachedPartsHandler { + /** + * Constructor + * @param c the parent component + * @throws IllegalArgumentException + */ public SubAssemblyHandler(final DocumentLoadingContext context, final RocketComponent c) throws IllegalArgumentException { - //A bit of a risk here, but assign the subassembly to the stage, not to the component. This is because typically the - //first component within the subassembly will be an external component. - super(context, c.getStage()); + super(context, c); } @Override @@ -33,9 +36,14 @@ public class SubAssemblyHandler extends AttachedPartsHandler { if (RockSimCommonConstants.ATTACHED_PARTS.equals(element)) { return this; } - // The key override of this class - treat body tubes as external body tubes. + // The key override of this class - treat body tubes, transitions, and nose cones as external components. + // note: this will only work if the parent component is a stage. else if (RockSimCommonConstants.BODY_TUBE.equals(element)) { return new BodyTubeHandler(getContext(), getComponent(), warnings); + } else if (RockSimCommonConstants.TRANSITION.equals(element)) { + return new TransitionHandler(getContext(), getComponent(), warnings); + } else if (RockSimCommonConstants.NOSE_CONE.equals(element)) { + return new NoseConeHandler(getContext(), getComponent(), warnings); } return super.openElement(element, attributes, warnings); } From a449d7b7f1e55012000b271baec070063069bc8f Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 4 Nov 2022 00:59:09 +0100 Subject: [PATCH 6/6] Add unit tests for RockSim SubAssembly import --- .../export/RockSimDocumentDTOTest.java | 2 +- .../rocksim/importt/RockSimLoaderTest.java | 115 +- .../file/rocksim/importt/SubAssemblyTest.rkt | 1684 +++++++++++++++++ 3 files changed, 1758 insertions(+), 43 deletions(-) create mode 100644 core/test/net/sf/openrocket/file/rocksim/importt/SubAssemblyTest.rkt diff --git a/core/test/net/sf/openrocket/file/rocksim/export/RockSimDocumentDTOTest.java b/core/test/net/sf/openrocket/file/rocksim/export/RockSimDocumentDTOTest.java index cbc82e30f..afaeef030 100644 --- a/core/test/net/sf/openrocket/file/rocksim/export/RockSimDocumentDTOTest.java +++ b/core/test/net/sf/openrocket/file/rocksim/export/RockSimDocumentDTOTest.java @@ -78,7 +78,7 @@ public class RockSimDocumentDTOTest extends RockSimTestBase { @Test public void testRoundTrip() throws Exception { // TODO need checks here to validate that correct things were done - OpenRocketDocument ord = RockSimLoaderTest.loadRockSimRocket3(new RockSimLoader()); + OpenRocketDocument ord = RockSimLoaderTest.loadRockSimRocket(new RockSimLoader(), "rocksimTestRocket3.rkt"); Assert.assertNotNull(ord); String result = new RockSimSaver().marshalToRockSim(ord); diff --git a/core/test/net/sf/openrocket/file/rocksim/importt/RockSimLoaderTest.java b/core/test/net/sf/openrocket/file/rocksim/importt/RockSimLoaderTest.java index 1a670d304..f6fef9447 100644 --- a/core/test/net/sf/openrocket/file/rocksim/importt/RockSimLoaderTest.java +++ b/core/test/net/sf/openrocket/file/rocksim/importt/RockSimLoaderTest.java @@ -8,6 +8,8 @@ import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; +import net.sf.openrocket.rocketcomponent.NoseCone; +import net.sf.openrocket.rocketcomponent.Transition; import org.junit.Assert; import net.sf.openrocket.document.OpenRocketDocument; @@ -20,6 +22,7 @@ import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.LaunchLug; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.util.BaseTestCase.BaseTestCase; +import org.junit.Test; /** * RockSimLoader Tester. @@ -59,7 +62,7 @@ public class RockSimLoaderTest extends BaseTestCase { public void testLoadFromStream() throws Exception { RockSimLoader loader = new RockSimLoader(); //Stupid single stage rocket - OpenRocketDocument doc = loadRockSimRocket(loader); + OpenRocketDocument doc = loadRockSimRocket(loader, "rocksimTestRocket1.rkt"); InputStream stream; Assert.assertNotNull(doc); @@ -149,7 +152,7 @@ public class RockSimLoaderTest extends BaseTestCase { public void testBodyTubeChildrenRocket() throws IOException, RocketLoadException { RockSimLoader loader = new RockSimLoader(); //Stupid single stage rocket - OpenRocketDocument doc = loadBodyTubeChildrenRocket(loader); + OpenRocketDocument doc = loadRockSimRocket(loader, "BodyTubeChildrenTest.rkt"); InputStream stream; Assert.assertNotNull(doc); @@ -188,10 +191,74 @@ public class RockSimLoaderTest extends BaseTestCase { Assert.assertEquals("Centering ring", subassemblyBodyTube.getChild(7).getName()); } - public static OpenRocketDocument loadRockSimRocket(RockSimLoader theLoader) throws IOException, RocketLoadException { - InputStream stream = RockSimLoaderTest.class.getResourceAsStream("rocksimTestRocket1.rkt"); - try { - Assert.assertNotNull("Could not open rocksimTestRocket1.rkt", stream); + @Test + public void testSubAssemblyRocket() throws IOException, RocketLoadException { + RockSimLoader loader = new RockSimLoader(); + OpenRocketDocument doc = loadRockSimRocket(loader, "SubAssemblyTest.rkt"); + + Assert.assertNotNull(doc); + Rocket rocket = doc.getRocket(); + Assert.assertNotNull(rocket); + Assert.assertEquals("SubAssembly Test", doc.getRocket().getName()); + Assert.assertEquals(2, loader.getWarnings().size()); // can't add BodyTube to NoseCone, and can't add Transition to Transition + + InputStream stream = this.getClass().getResourceAsStream("SubAssemblyTest.rkt"); + Assert.assertNotNull("Could not open SubAssemblyTest.rkt", stream); + + doc = OpenRocketDocumentFactory.createEmptyRocket(); + DocumentLoadingContext context = new DocumentLoadingContext(); + context.setOpenRocketDocument(doc); + context.setMotorFinder(new DatabaseMotorFinder()); + loader.loadFromStream(context, new BufferedInputStream(stream)); + + Assert.assertNotNull(doc); + rocket = doc.getRocket(); + Assert.assertNotNull(rocket); + Assert.assertEquals(1, rocket.getStageCount()); + AxialStage stage1 = (AxialStage) rocket.getChild(0); + + Assert.assertEquals(5, stage1.getChildCount()); + NoseCone noseCone1 = (NoseCone) stage1.getChild(0); + BodyTube bodyTube2 = (BodyTube) stage1.getChild(1); + Transition transition1 = (Transition) stage1.getChild(2); + Transition transition3 = (Transition) stage1.getChild(3); + BodyTube bodyTube3 = (BodyTube) stage1.getChild(4); + Assert.assertEquals("Nose cone 1", noseCone1.getName()); + Assert.assertEquals("Body tube 2", bodyTube2.getName()); + Assert.assertEquals("Transition 1", transition1.getName()); + Assert.assertEquals("Transition 3", transition3.getName()); + Assert.assertEquals("Body tube 3", bodyTube3.getName()); + + Assert.assertEquals(1, noseCone1.getChildCount()); + Assert.assertEquals("Mass object 1", noseCone1.getChild(0).getName()); + + Assert.assertEquals(12, bodyTube2.getChildCount()); + Assert.assertEquals("Mass object 2", bodyTube2.getChild(0).getName()); + Assert.assertEquals("Launch lug 1", bodyTube2.getChild(1).getName()); + Assert.assertEquals("Centering ring 1", bodyTube2.getChild(2).getName()); + Assert.assertEquals("Tube coupler 1", bodyTube2.getChild(3).getName()); + Assert.assertEquals("Fin set 1", bodyTube2.getChild(4).getName()); + Assert.assertEquals("Fin set 2", bodyTube2.getChild(5).getName()); + Assert.assertEquals("Parachute 1", bodyTube2.getChild(6).getName()); + Assert.assertEquals("Streamer 1", bodyTube2.getChild(7).getName()); + Assert.assertEquals("Bulkhead 1", bodyTube2.getChild(8).getName()); + Assert.assertEquals("Engine block 1", bodyTube2.getChild(9).getName()); + Assert.assertEquals("Tube fins 1", bodyTube2.getChild(10).getName()); + Assert.assertEquals("Sleeve 1", bodyTube2.getChild(11).getName()); + + Assert.assertEquals(3, transition1.getChildCount()); + Assert.assertEquals("Mass object 3", transition1.getChild(0).getName()); + Assert.assertEquals("Fin set 3", transition1.getChild(1).getName()); + Assert.assertEquals("Fin set 4", transition1.getChild(2).getName()); + + Assert.assertEquals(0, transition3.getChildCount()); + + Assert.assertEquals(0, bodyTube3.getChildCount()); + } + + public static OpenRocketDocument loadRockSimRocket(RockSimLoader theLoader, String fileName) throws IOException, RocketLoadException { + try (InputStream stream = RockSimLoaderTest.class.getResourceAsStream(fileName)) { + Assert.assertNotNull("Could not open " + fileName, stream); OpenRocketDocument doc = OpenRocketDocumentFactory.createEmptyRocket(); DocumentLoadingContext context = new DocumentLoadingContext(); context.setOpenRocketDocument(doc); @@ -199,41 +266,5 @@ public class RockSimLoaderTest extends BaseTestCase { theLoader.loadFromStream(context, new BufferedInputStream(stream)); return doc; } - finally { - stream.close(); - } } - - public static OpenRocketDocument loadRockSimRocket3(RockSimLoader theLoader) throws IOException, RocketLoadException { - InputStream stream = RockSimLoaderTest.class.getResourceAsStream("rocksimTestRocket3.rkt"); - try { - Assert.assertNotNull("Could not open rocksimTestRocket3.rkt", stream); - OpenRocketDocument doc = OpenRocketDocumentFactory.createEmptyRocket(); - DocumentLoadingContext context = new DocumentLoadingContext(); - context.setOpenRocketDocument(doc); - context.setMotorFinder(new DatabaseMotorFinder()); - theLoader.loadFromStream(context, new BufferedInputStream(stream)); - return doc; - } - finally { - stream.close(); - } - } - - public static OpenRocketDocument loadBodyTubeChildrenRocket(RockSimLoader theLoader) throws IOException, RocketLoadException { - InputStream stream = RockSimLoaderTest.class.getResourceAsStream("BodyTubeChildrenTest.rkt"); - try { - Assert.assertNotNull("Could not open BodyTubeChildrenTest.rkt", stream); - OpenRocketDocument doc = OpenRocketDocumentFactory.createEmptyRocket(); - DocumentLoadingContext context = new DocumentLoadingContext(); - context.setOpenRocketDocument(doc); - context.setMotorFinder(new DatabaseMotorFinder()); - theLoader.loadFromStream(context, new BufferedInputStream(stream)); - return doc; - } - finally { - stream.close(); - } - } - } diff --git a/core/test/net/sf/openrocket/file/rocksim/importt/SubAssemblyTest.rkt b/core/test/net/sf/openrocket/file/rocksim/importt/SubAssemblyTest.rkt new file mode 100644 index 000000000..06a226c9e --- /dev/null +++ b/core/test/net/sf/openrocket/file/rocksim/importt/SubAssemblyTest.rkt @@ -0,0 +1,1684 @@ + +4 + + +SubAssembly Test +1 +1 +1 +0.75 +0.8 +0.81 +0.95 +0.95 +1 +0. +0. +0. +0. +0. +0. +0. +0. +4 +914.4 +0 +0 +0 +1 +0 +4 +48 +1 +0 +0,161.293,0,0 +0,33.4942,0,0 +0,172.472,0,0 +0,46.4108,0,0 +0,0,0,0 +0,0,0,0 +0 +1 +0 +1 +0. +0. +0 +0 +0 +0 +0 +0 +0 +0 +0. +10. +10. +10. +10. +0 +0 +0 +10. +0.15 +black +233.93 +78.74 +863.6 +863.6 +0. +863.6 +0,78.74,0,0 +0,863.6,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,0,0 + + + + + + +Apogee +23.5 +88.1015 +Flexible Urethane Foam - firm +Nose cone 1 +63.5 +1 +0. +9.28808 +39.6875 +0.00944361 +0.00944361 +0. +0 +14811 +56mm TARC Foam Nose Cone +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +1 +1 +0 +0 +blue +2. +0.0211667 +2. +0.0211667 +1 +0 +8 +0 +0. +63.5 +56.31 +0 +3 +0 +0. +0. +0. +0. +0. +0. +0. + + +Custom +0. +0. +Custom +Subassembly 1 +0. +0 +0. +0. +0. +0. +0. +0. +0 +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +7 +1 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +0. + + +Apogee +41.4 +0. +Mass object 1 +0. +1 +0. +0. +0. +0. +0. +0. +0 +29633 + +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +15 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +0. +0 +0. + + + + +Apogee +0. +1121.29 +Paper +Body tube 1 +0. +0 +0. +80.3519 +431.8 +0.0833729 +0.0833729 +0. +0 +10251 + +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +47 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +0. +30.73 +28.96 +863.6 +0 +0 +0. +0.5 +0. +0. +0 +0 + + + + + + + + +Apogee +0. +1121.29 +Paper +Body tube 2 +0. +0 +0. +11.621 +62.45 +0.012058 +0.012058 +0. +0 +10251 + +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +2 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 +30.73 +28.96 +124.9 +0 +0 +0. +0.5 +0. +0. +0 +0 + + +Custom +0. +0. +Custom +Subassembly 2 +0. +0 +0. +0. +0. +0. +0. +0. +0 +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +8 +1 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 + + +AeroPack +6.8 +0. +Aluminum +Mass object 2 +0. +1 +0. +0. +0. +0. +0. +0. +0 +24051 +24mm Aeropack Retainer - L +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +18 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 +0 +0. + + + + +Public Missiles +0. +8553.86 +Brass +Launch lug 1 +0. +0 +0. +34.8781 +152.4 +0.0173643 +0.00912552 +0. +0 +LL-0.38 +3/8in Brass Launch Lug +20.13 +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +22 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 +9.53 +8.59 +304.8 +0 + + + + +Apogee +0. +400.462 +Cardstock +Centering ring 1 +0. +0 +0. +0.512713 +0.635 +0. +0. +0. +0 +13394 +CR 13-41.6 Cardstock +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +24 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 +40.46 +13.87 +1.27 +0 +0 +0 + + + + +Apogee +63.786 +1121.29 +Paper +Tube coupler 1 +0. +1 +0. +2.40724 +31.75 +0. +0. +0. +0 +13010 +AC-29A +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +27 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 +28.7 +27.94 +63.5 +0 +4 +0 + + + + +Apogee +0. +128.148 +Balsa +Fin set 1 +0. +0 +63.44 +2.55121 +27.6561 +0.00417366 +0.012521 +0. +0 +15645 +Avion Fins +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +26 +0 +0 +0 +blue +5.24169 +0.144771 +7.498 +0.144771 +1 +0 +8 +0 +126.94 +3 +53.98 +19.05 +57.15 +57.172 +19.05 +3.18 +0 +0 +0 +0. +0. +0. +1 +0.320006 +0. +39.3842 +4.32897 +0.352908 +0. +0. + + + + +Public Missiles +0. +1905.24 +G10 fiberglass +Fin set 2 +0. +0 +63.44 +51.2497 +43.164 +0.0112786 +0.0338357 +0. +0 + +Fins +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +rgb(126,150,121) +white +1 +29 +0 +0 +0 +rgb(61,177,187) +14.1955 +0.15664 +18.9793 +0.154953 +1 +0 +8 +0 +126.94 +3 +101.6 +8.21 +101.6 +102.231 +35.35 +1.59 +2 +0 +0 +0. +0. +0. +1 +0. +0. +51.7637 +10.9577 +0.0808071 +0. +0. +61.25 +8.20927 +101.6,0|76.2,61.46|25.4,101.6|0,0| +0,0,0,0,0,0,0 +10,10,10,10,10,10,10 +0,0,0,0,0,0,0 +0.5,10,0.5,0.5,0.00018939,0.001,1 +0.25,5,0.1,0.1,0.00018939,0.001,1 +0,0,0,0,0,0,0 +10,10,10,10,10,10,10 +0,0,0,0,0,0,0 +0.5,10,0.5,0.5,0.00018939,0.001,1 +0.25,5,0.1,0.1,0.00018939,0.001,1 + + + + +Apogee +7.5 +0. +Rip stop nylon +Parachute 1 +0. +1 +0. +0.75374 +31.75 +0. +0. +0. +0 +29091 + +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +25 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 +381. +0. +6 +6 +0.76 +381. +1 +0.00032972 +Carpet String (Apogee 29500) +0.75 + + + + +Apogee +0. +1309. +Mylar +Streamer 1 +0. +0 +0. +1891.71 +50.8 +0. +0. +0. +0 +30305 +4in x 56in Mylar +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +28 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 +1422.4 +101.6 +10. +1 +0.13 +0 +1 + + + + +Aerospace Speciality Products +0. +724.996 +Aircraft plywood (Birch) +Bulkhead 1 +0. +0 +0. +1.51385 +1.585 +0. +0. +0. +0 +PBH-70 +Plywood Bulkhead 70 (fits TC70 Coupler) +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +30 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 +28.96 +0. +3.17 +0 +1 +1 + + + + +Apogee +1.8 +1121.29 +Paper +Engine block 1 +0. +1 +0. +1.12787 +3.175 +0. +0. +0. +0 +13035 +CR 24-29 ring +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +32 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 +28.7 +24.94 +6.35 +0 +2 +0 + + + + +Custom +0. +1121.29 +Paper +Tube fins 1 +0. +0 +0. +5.17189 +38.1 +0.0264173 +0.0264173 +0. +0 +1 +Test tube fins save 1 +24.715 +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +33 +0 +0 +0 +blue +4.7033 +0.637977 +1.08811 +0.071517 +1 +0 +8 +0 +63.5 +18.7 +18. +76.2 +0 +3 +0.775946 +8 + + + + +Apogee +5.4 +1121.29 +Paper +Sleeve 1 +0. +1 +0. +7.66959 +50.8 +0. +0. +0. +0 +10090 +AS-24 +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +34 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +63.5 +26.8 +25.15 +101.6 +0 +3 +0 + + + + + + + + +LOC Precision +0.25 +1049.21 +Polystyrene PS +Transition 1 +107.95 +0 +0. +54.365 +41.7981 +0.0170804 +0.0170804 +0. +0 +AR-3.00-2.14 +Airframe Reducer from 3.00 to 2.14 +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +3 +1 +0 +0 +blue +1.83262 +0.230096 +1.83262 +0.230096 +1 +0 +8 +0 +188.4 +57.4 +78.74 +79.25 +0 +0. +0. +1 +3.18 +0. +0. +0. +0 +0. +292.389 +213.139 + + +Custom +0. +0. +Custom +Subassembly 3 +0. +0 +0. +0. +0. +0. +0. +0. +0 +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +9 +1 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +188.4 + + +Apogee +8.5 +0. +Aluminum +Mass object 3 +0. +1 +0. +0. +0. +0. +0. +0. +0 +29620 + +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +39 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +188.4 +0 +0. + + + + +Aerospace Speciality Products +0. +1905.24 +G10 phenolic +Fin set 3 +0. +0 +0. +1.43908 +12.423 +0.00122818 +0.00368454 +0. +0 +FGST16 +G10 Fin Sm Trap (0.016) +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +43 +0 +0 +0 +blue +1.98949 +0.195851 +3.35146 +0.195851 +1 +0 +8 +0 +188.4 +3 +25.4 +15.9 +31.8 +31.8 +4.76 +0.41 +0 +0 +0 +0. +0. +0. +1 +0.149994 +0. +43.3799 +1.93497 +0.625984 +0. +0. + + + + +Public Missiles +0. +1905.24 +G10 fiberglass +Fin set 4 +0. +0 +0. +64.1326 +118.675 +0.0140255 +0.0420765 +0. +0 +FIN-MBBX-LWR +Lower fins +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +rgb(126,150,121) +white +1 +44 +0 +0 +0 +rgb(61,177,187) +9.81031 +0.275032 +14.3248 +0.278513 +1 +0 +8 +0 +188.4 +3 +146.05 +84.18 +69.84 +117.616 +125.57 +1.6 +2 +0 +0 +0. +0. +0. +1 +0. +0. +60.491 +8.27043 +0.576378 +0. +0. +118.44 +84.183 +146.05,0|165.1,9.525|200.025,69.84|120.65,69.633|0,0| +0,0,0,0,0,0,0 +10,10,10,10,10,10,10 +0,0,0,0,0,0,0 +0.5,10,0.5,0.5,0.00018939,0.001,1 +0.25,5,0.1,0.1,0.00018939,0.001,1 +0,0,0,0,0,0,0 +10,10,10,10,10,10,10 +0,0,0,0,0,0,0 +0.5,10,0.5,0.5,0.00018939,0.001,1 +0.25,5,0.1,0.1,0.00018939,0.001,1 + + + + +Apogee +0. +1049.21 +Polystyrene PS +Transition 2 +0. +0 +0. +13.106 +26.1291 +0.00980779 +0.00980779 +0. +0 +17081 +BT-70/BT-80 Blow Mold Transition +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +48 +0 +0 +0 +blue +0.772815 +0.2138 +0.772815 +0.2138 +1 +0 +8 +0 +188.4 +56. +66.04 +50.8 +0 +0. +0. +1 +1.3 +0. +0. +0. +2 +0. +180.826 +130.026 + + + + + + + + +Custom +0. +0. +Custom +Subassembly 4 +0. +0 +0. +0. +0. +0. +0. +0. +0 +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +4 +1 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +267.65 + + +LOC Precision +0.238 +1049.21 +Polystyrene PS +Transition 3 +82.5 +0 +0. +190.756 +97.0467 +0.0593746 +0.0593746 +0. +0 +PTC-3.90 +Tail Cone +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +5 +0 +0 +0 +blue +-3.4363 +0.400114 +-3.4363 +0.400114 +1 +0 +8 +0 +267.65 +102. +70.4 +206. +0 +0. +0. +1 +3.17 +0. +0. +0. +1 +0. +367.667 +161.667 + + + + +Apogee +0. +1199.78 +Polycarbonate +Body tube 3 +0. +0 +0. +5.35012 +76.2 +0.0119168 +0.0119168 +0. +0 +10102 + +0. +0. +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)|rotate=(0) +1. +0. +1. +0. +1. +blue +blue +white +1 +6 +0 +0 +0 +blue +0. +0. +0. +0. +1 +0 +8 +0 +473.65 +24.89 +24.13 +152.4 +0 +0 +0. +0.5 +0. +0. +0 +0 + + + + + + + + + + + + + + + + + + + + +