From 9f5fb060d27bf5954283f1119ac1e2089c01b0d2 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Tue, 18 Oct 2022 21:40:14 +0200 Subject: [PATCH] [#1750] Separate override subcomponents to mass, CG, and CD subcomponents override --- core/resources/l10n/messages.properties | 14 ++- core/resources/l10n/messages_cs.properties | 2 +- core/resources/l10n/messages_es.properties | 2 +- core/resources/l10n/messages_fr.properties | 2 +- core/resources/l10n/messages_it.properties | 2 +- core/resources/l10n/messages_ja.properties | 2 +- core/resources/l10n/messages_nl.properties | 2 +- core/resources/l10n/messages_pl.properties | 2 +- core/resources/l10n/messages_pt.properties | 2 +- core/resources/l10n/messages_uk_UA.properties | 2 +- .../openrocket/importt/DocumentConfig.java | 8 ++ .../savers/RocketComponentSaver.java | 14 +-- .../file/rocksim/importt/BaseHandler.java | 3 +- .../file/rocksim/importt/RocksimHandler.java | 12 +- .../openrocket/masscalc/MassCalculation.java | 10 +- .../rocketcomponent/RocketComponent.java | 109 +++++++++++++++--- .../net/sf/openrocket/util/TestRockets.java | 3 +- .../masscalc/MassCalculatorTest.java | 23 ++-- .../rocketcomponent/FreeformFinSetTest.java | 9 +- .../rocketcomponent/OverrideTest.java | 12 +- .../configdialog/RocketComponentConfig.java | 72 ++++++++---- 21 files changed, 216 insertions(+), 91 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 8ed4c4f79..69831ccae 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -924,12 +924,14 @@ RocketCompCfg.but.Setforall = Set for all RocketCompCfg.but.ttip.Setforall = Set this finish for all components of the rocket. RocketCompCfg.checkbox.Overridemass = Override mass: RocketCompCfg.checkbox.Overridemass.ttip = Overrides the mass of the component calculated by the component's volume and density. -RocketCompCfg.checkbox.Overridecenterofgrav = Override center of gravity: -RocketCompCfg.checkbox.Overridecenterofgrav.ttip = Overrides the component's center of gravity location. -RocketCompCfg.checkbox.SetDragCoeff = Override coefficient of drag: -RocketCompCfg.checkbox.SetDragCoeff.ttip = Overrides the component's coefficient of drag. -RocketCompCfg.checkbox.OverrideSubcomponents = Override mass, CG, and CD of all subcomponents -RocketCompCfg.checkbox.OverrideSubcomponents.ttip = Overrides the aggregate mass, center of gravity (CG), and coefficient of drag (CD) of this component
and its subcomponents with the mass, CG, and CD of this component. +RocketCompCfg.checkbox.Overridecenterofgrav = Override center of gravity CG: +RocketCompCfg.checkbox.Overridecenterofgrav.ttip = Overrides the component's center of gravity (CG) location. +RocketCompCfg.checkbox.SetDragCoeff = Override coefficient of drag CD: +RocketCompCfg.checkbox.SetDragCoeff.ttip = Overrides the component's coefficient of drag CD. +RocketCompCfg.checkbox.OverrideSubcomponents = Override for all subcomponents +RocketCompCfg.checkbox.OverrideSubcomponents.Mass.ttip = Overrides the aggregate mass of this component
and its subcomponents with the mass of this component. +RocketCompCfg.checkbox.OverrideSubcomponents.CG.ttip = Overrides the center of gravity (CG) of this component
and its subcomponents with the CG of this component. +RocketCompCfg.checkbox.OverrideSubcomponents.CD.ttip = Overrides the coefficient of drag (CD) of this component
and its subcomponents with the CD of this component. RocketCompCfg.lbl.longB1 = The overridden mass and center of gravity does not include motors.
RocketCompCfg.lbl.longB2 = The center of gravity is measured from the front end of the RocketCompCfg.lbl.Commentsonthe = Comments on the diff --git a/core/resources/l10n/messages_cs.properties b/core/resources/l10n/messages_cs.properties index 3e9b5ea5f..619f8419d 100644 --- a/core/resources/l10n/messages_cs.properties +++ b/core/resources/l10n/messages_cs.properties @@ -642,7 +642,7 @@ RocketCompCfg.but.Setforall = Nastav pro v\u0161echny RocketCompCfg.but.ttip.Setforall = Nastav povrchovou úpravu pro v\u0161echny komponenty rakety. RocketCompCfg.checkbox.Overridemass = Zmen hmotnost: RocketCompCfg.checkbox.Overridecenterofgrav = Zmen te\u017Ei\u0161te: -RocketCompCfg.checkbox.OverrideSubcomponents = Zmen hmotnost a te\u017Ei\u0161te v\u0161ech komponent +RocketCompCfg.checkbox.OverrideSubcomponents = P\u0159eps\u00E1n\u00ED pro v\u0161echny d\u00EDl\u010D\u00ED sou\u010D\u00E1sti RocketCompCfg.lbl.longB1 = Zmena hmotnosti nezahrnuje motory.
RocketCompCfg.lbl.longB2 = Te\u017Ei\u0161te je mereno od predku RocketCompCfg.lbl.Commentsonthe = Komentár na diff --git a/core/resources/l10n/messages_es.properties b/core/resources/l10n/messages_es.properties index 7bfe090c5..3dee931c1 100644 --- a/core/resources/l10n/messages_es.properties +++ b/core/resources/l10n/messages_es.properties @@ -831,7 +831,7 @@ RocketCompCfg.but.ttip.Setforall = Aplicar este acabado a todos RocketCompCfg.checkbox.Endcapped = Extremo tapado RocketCompCfg.checkbox.Overridecenterofgrav = Especificar el CG: RocketCompCfg.checkbox.Overridemass = Especificar la masa: -RocketCompCfg.checkbox.OverrideSubcomponents = Incluir la masa y el CG de todos los subcomponentes +RocketCompCfg.checkbox.OverrideSubcomponents = Incluir de todos los subcomponentes RocketCompCfg.checkbox.Usedefaultcolor = Usar color por defecto RocketCompCfg.combo.ttip.componentmaterialaffects = El peso del componente depender\u00e1 del material seleccionado. RocketCompCfg.lbl.Choosecolor = Elija color diff --git a/core/resources/l10n/messages_fr.properties b/core/resources/l10n/messages_fr.properties index 210605775..0e9ea5cdb 100644 --- a/core/resources/l10n/messages_fr.properties +++ b/core/resources/l10n/messages_fr.properties @@ -823,7 +823,7 @@ RocketCompCfg.checkbox.Endcapped = Arri\u00E8re clos RocketCompCfg.checkbox.Overridecenterofgrav = Forcer le centre de gravit\u00E9: RocketCompCfg.checkbox.Overridecoeffofdrag = Modifier le coefficient de trainee: RocketCompCfg.checkbox.Overridemass = Forcer la masse: -RocketCompCfg.checkbox.OverrideSubcomponents = Forcer la masse et le centre de gravit\u00E9 de tous les sous composants +RocketCompCfg.checkbox.OverrideSubcomponents = Forcer pour tous les sous composants RocketCompCfg.checkbox.Usedefaultcolor = Utiliser la couleur par d\u00E9faut RocketCompCfg.combo.ttip.componentmaterialaffects = Les mat\u00E9riaux utilis\u00E9s pour la pi\u00E8ce affectent le poids de la pi\u00E8ce. RocketCompCfg.lbl.Choosecolor = Choisir la couleur diff --git a/core/resources/l10n/messages_it.properties b/core/resources/l10n/messages_it.properties index 784de45de..f8b4cb3f0 100644 --- a/core/resources/l10n/messages_it.properties +++ b/core/resources/l10n/messages_it.properties @@ -700,7 +700,7 @@ RocketCompCfg.but.Setforall = Imposta per tutti RocketCompCfg.but.ttip.Setforall = Imposta questa finitura per tutti i componenti del razzo. RocketCompCfg.checkbox.Overridemass = Modifica la massa: RocketCompCfg.checkbox.Overridecenterofgrav = Sposta il centro di gravita': -RocketCompCfg.checkbox.OverrideSubcomponents = Modifica la massa ed il CG di tutti i subcomponenti +RocketCompCfg.checkbox.OverrideSubcomponents = Modifica di tutti i subcomponenti RocketCompCfg.lbl.longB1 = La massa modificata non include i motori.
RocketCompCfg.lbl.longB2 = Il Centro di Gravita' e' misurato dall'inizio di RocketCompCfg.lbl.Commentsonthe = Commenti sul diff --git a/core/resources/l10n/messages_ja.properties b/core/resources/l10n/messages_ja.properties index 7286f837c..4b6f4f3ce 100644 --- a/core/resources/l10n/messages_ja.properties +++ b/core/resources/l10n/messages_ja.properties @@ -730,7 +730,7 @@ RocketCompCfg.but.Setforall = \u5168\u3066\u306B\u9069\u7528 RocketCompCfg.but.ttip.Setforall = \u3053\u306E\u4ED5\u4E0A\u3052\u65B9\u3092\u5168\u3066\u306E\u90E8\u54C1\u306B\u9069\u7528\u3059\u308B RocketCompCfg.checkbox.Overridemass = \u8CEA\u91CF\u306E\u518D\u5B9A\u7FA9\uFF1A RocketCompCfg.checkbox.Overridecenterofgrav = \u91CD\u5FC3\u306E\u518D\u5B9A\u7FA9\uFF1A -RocketCompCfg.checkbox.OverrideSubcomponents = \u5168\u3066\u306E\u30B5\u30D6\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306E\u8CEA\u91CF\u3068CG\u3092\u518D\u5B9A\u7FA9\uFF1A +RocketCompCfg.checkbox.OverrideSubcomponents = \u3059\u3079\u3066\u306e\u30b5\u30d6\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306b\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3059\u308b RocketCompCfg.lbl.longB1 = \u518D\u5B9A\u7FA9\u3055\u308C\u305F\u8CEA\u91CF\u306B\u306F\u30E2\u30FC\u30BF\u30FC\u306F\u542B\u307E\u308C\u306A\u3044
RocketCompCfg.lbl.longB2 = \u91CD\u5FC3\u306F\u90E8\u54C1\u306E\u524D\u65B9\u7AEF\u304B\u3089\u3001\u90E8\u54C1\uFF1A RocketCompCfg.lbl.Commentsonthe = \u30B3\u30E1\u30F3\u30C8\uFF1A diff --git a/core/resources/l10n/messages_nl.properties b/core/resources/l10n/messages_nl.properties index d1d153caf..a207ab420 100644 --- a/core/resources/l10n/messages_nl.properties +++ b/core/resources/l10n/messages_nl.properties @@ -851,7 +851,7 @@ RocketCompCfg.but.ttip.Setforall = Stel deze afwerking in voor alle onderdelen v RocketCompCfg.checkbox.Overridemass = Overschrijf massa: RocketCompCfg.checkbox.Overridecenterofgrav = Overschrijf zwaartepunt: RocketCompCfg.checkbox.SetDragCoeff = Stel wrijvingscoëfficiënt in: -RocketCompCfg.checkbox.OverrideSubcomponents = Massa en zwaartepunt van alle subonderdelen overschrijven +RocketCompCfg.checkbox.OverrideSubcomponents = Voor alle subonderdelen overschrijven RocketCompCfg.lbl.longB1 = De overschreven massa omvat geen motoren.
RocketCompCfg.lbl.longB2 = Het zwaartepunt wordt gemeten vanaf de voorkant van de RocketCompCfg.lbl.Commentsonthe = Opmerkingen over de diff --git a/core/resources/l10n/messages_pl.properties b/core/resources/l10n/messages_pl.properties index f3cbe0a19..3b5bd6b0e 100644 --- a/core/resources/l10n/messages_pl.properties +++ b/core/resources/l10n/messages_pl.properties @@ -644,7 +644,7 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s. RocketCompCfg.but.ttip.Setforall = Nadaj to wyko\u0144czenie wszystkim cz\u0119\u015Bci\u0105 sk\u0142adow\u0105 rakiety. RocketCompCfg.checkbox.Overridemass = Wymu\u015B ci\u0119\u017Car: RocketCompCfg.checkbox.Overridecenterofgrav = Wymu\u015B \u015Brodek ci\u0119\u017Cko\u015Bci: - RocketCompCfg.checkbox.OverrideSubcomponents = Wymu\u015B ci\u0119\u017Car oraz \u015Brodek ci\u0119\u017Cko\u015Bci wszystkich dodatkowych cz\u0119\u015Bci sk\u0142adowych + RocketCompCfg.checkbox.OverrideSubcomponents = Nadpisanie dla wszystkich podkomponent\u00F3w RocketCompCfg.lbl.longB1 = Wymuszony ci\u0119\u017Car nie uwzgl\u0119dnia silników.
RocketCompCfg.lbl.longB2 = \u015Arodek ci\u0119\u017Cko\u015Bci jest mierzony od przodu RocketCompCfg.lbl.Commentsonthe = Uwagi - diff --git a/core/resources/l10n/messages_pt.properties b/core/resources/l10n/messages_pt.properties index 67a3df719..af3120d63 100644 --- a/core/resources/l10n/messages_pt.properties +++ b/core/resources/l10n/messages_pt.properties @@ -809,7 +809,7 @@ RocketCompCfg.checkbox.Endcapped = Fim tampado RocketCompCfg.checkbox.Overridecenterofgrav = Modificar o centro de gravidade: RocketCompCfg.checkbox.Overridecoeffofdrag = Modificar o coeficiente de arrasto: RocketCompCfg.checkbox.Overridemass = Modificar massa: -RocketCompCfg.checkbox.OverrideSubcomponents = Modificar a massa e o CG de todos os subcomponentes +RocketCompCfg.checkbox.OverrideSubcomponents = Modificar de todos os subcomponentes RocketCompCfg.checkbox.Usedefaultcolor = Use a cor padr\u00e3o RocketCompCfg.combo.ttip.componentmaterialaffects = O material do componente afeta o peso do componente. RocketCompCfg.lbl.Choosecolor = Escolha a cor diff --git a/core/resources/l10n/messages_uk_UA.properties b/core/resources/l10n/messages_uk_UA.properties index e0745534d..4dd2ea040 100644 --- a/core/resources/l10n/messages_uk_UA.properties +++ b/core/resources/l10n/messages_uk_UA.properties @@ -802,7 +802,7 @@ RocketCompCfg.but.ttip.Setforall = Set this finish for all components of the roc RocketCompCfg.checkbox.Overridemass = Override mass: RocketCompCfg.checkbox.Overridecenterofgrav = Override center of gravity: RocketCompCfg.checkbox.Overridecoeffofdrag = Override coefficient of drag: -RocketCompCfg.checkbox.OverrideSubcomponents = Override mass and CG of all subcomponents +RocketCompCfg.checkbox.OverrideSubcomponents = Override for all subcomponents RocketCompCfg.lbl.longB1 = The overridden mass does not include motors.
RocketCompCfg.lbl.longB2 = The center of gravity is measured from the front end of the RocketCompCfg.lbl.Commentsonthe = Comments on the diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java index 60a20db09..3fe4093e6 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java @@ -129,8 +129,16 @@ class DocumentConfig { setters.put("RocketComponent:overridecd", new OverrideSetter( Reflection.findMethod(RocketComponent.class, "setOverrideCD", double.class), Reflection.findMethod(RocketComponent.class, "setCDOverridden", boolean.class))); + // TODO: delete overridesubcomponents setters if no compatibility is needed anymore with OR 15.03 setters.put("RocketComponent:overridesubcomponents", new BooleanSetter( Reflection.findMethod(RocketComponent.class, "setSubcomponentsOverridden", boolean.class))); + + setters.put("RocketComponent:overridesubcomponentsmass", new BooleanSetter( + Reflection.findMethod(RocketComponent.class, "setSubcomponentsOverriddenMass", boolean.class))); + setters.put("RocketComponent:overridesubcomponentscg", new BooleanSetter( + Reflection.findMethod(RocketComponent.class, "setSubcomponentsOverriddenCG", boolean.class))); + setters.put("RocketComponent:overridesubcomponentscd", new BooleanSetter( + Reflection.findMethod(RocketComponent.class, "setSubcomponentsOverriddenCD", boolean.class))); setters.put("RocketComponent:comment", new StringSetter( Reflection.findMethod(RocketComponent.class, "setComment", String.class))); setters.put("RocketComponent:preset", new ComponentPresetSetter( diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java index 9e45ee05f..2ae1b1085 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java @@ -128,22 +128,20 @@ public class RocketComponentSaver { } // Overrides - boolean overridden = false; if (c.isMassOverridden()) { elements.add("" + c.getOverrideMass() + ""); - overridden = true; + elements.add("" + c.isSubcomponentsOverriddenMass() + + ""); } if (c.isCGOverridden()) { elements.add("" + c.getOverrideCGX() + ""); - overridden = true; + elements.add("" + c.isSubcomponentsOverriddenCG() + + ""); } if (c.isCDOverridden()) { elements.add("" + c.getOverrideCD() + ""); - overridden = true; - } - if (overridden) { - elements.add("" + c.isSubcomponentsOverridden() - + ""); + elements.add("" + c.isSubcomponentsOverriddenCD() + + ""); } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java index 9eafaad71..a3ca432fb 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java @@ -175,7 +175,8 @@ public abstract class BaseHandler extends AbstractEle if (override) { component.setCGOverridden(override); component.setMassOverridden(override); - component.setSubcomponentsOverridden(false); //Rocksim does not support this type of override + component.setSubcomponentsOverriddenMass(false); //Rocksim does not support this type of override + component.setSubcomponentsOverriddenCG(false); //Rocksim does not support this type of override component.setOverrideMass(mass); component.setOverrideCGX(cg); } 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 2dd64e5ea..a2692bc8c 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java @@ -208,12 +208,12 @@ class RocketDesignHandler extends AbstractElementHandler { final AxialStage stage = new AxialStage(); if (stage3Mass > 0.0d) { stage.setMassOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenMass(true); //Rocksim does not support this type of override stage.setOverrideMass(stage3Mass); } if (stage3CG > 0.0d) { stage.setCGOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenCG(true); //Rocksim does not support this type of override stage.setOverrideCGX(stage3CG); } component.addChild(stage); @@ -224,12 +224,12 @@ class RocketDesignHandler extends AbstractElementHandler { final AxialStage stage = new AxialStage(); if (stage2Mass > 0.0d) { stage.setMassOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenMass(true); //Rocksim does not support this type of override stage.setOverrideMass(stage2Mass); } if (stage2CG > 0.0d) { stage.setCGOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenCG(true); //Rocksim does not support this type of override stage.setOverrideCGX(stage2CG); } component.addChild(stage); @@ -241,12 +241,12 @@ class RocketDesignHandler extends AbstractElementHandler { final AxialStage stage = new AxialStage(); if (stage1Mass > 0.0d) { stage.setMassOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenMass(true); //Rocksim does not support this type of override stage.setOverrideMass(stage1Mass); } if (stage1CG > 0.0d) { stage.setCGOverridden(true); - stage.setSubcomponentsOverridden(true); //Rocksim does not support this type of override + stage.setSubcomponentsOverriddenCG(true); //Rocksim does not support this type of override stage.setOverrideCGX(stage1CG); } component.addChild(stage); diff --git a/core/src/net/sf/openrocket/masscalc/MassCalculation.java b/core/src/net/sf/openrocket/masscalc/MassCalculation.java index 70c14e1b9..cc925053b 100644 --- a/core/src/net/sf/openrocket/masscalc/MassCalculation.java +++ b/core/src/net/sf/openrocket/masscalc/MassCalculation.java @@ -355,16 +355,16 @@ public class MassCalculation { // setting zero as the CG position means the top of the component, which is component.getPosition() final Coordinate compZero = parentTransform.transform( component.getPosition() ); - if (component.isSubcomponentsOverridden()) { - if( component.isMassive() ){ + if (component.isSubcomponentsOverriddenMass() || component.isSubcomponentsOverriddenCG()) { + if (component.isMassive()) { // if this component mass, merge it in before overriding: this.addMass( compCM ); } - if (component.isMassOverridden()) { + if (component.isSubcomponentsOverriddenMass() && component.isMassOverridden()) { this.setCM( this.getCM().setWeight(component.getOverrideMass()) ); } - if (component.isCGOverridden()) { - this.setCM( this.getCM().setX( compZero.x + component.getOverrideCGX())); + if (component.isSubcomponentsOverriddenCG() && component.isCGOverridden()) { + this.setCM( this.getCM().setX(compZero.x + component.getOverrideCGX())); } }else { if (component.isMassOverridden()) { diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index 1e165d81e..77301a62d 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -99,15 +99,17 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab // Override mass/CG/CD protected double overrideMass = 0; protected boolean massOverridden = false; + private boolean overrideSubcomponentsMass = false; private double overrideCGX = 0; private boolean cgOverridden = false; + private boolean overrideSubcomponentsCG = false; private double overrideCD = 0; private boolean cdOverridden = false; + private boolean overrideSubcomponentsCD = false; private boolean cdOverriddenByAncestor = false; - private boolean overrideSubcomponents = false; // User-given name of the component @@ -707,7 +709,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab this.overrideCD = x; if (isCDOverridden()) { - if (isSubcomponentsOverridden()) { + if (isSubcomponentsOverriddenCD()) { overrideSubcomponentsCD(true); } fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE); @@ -749,7 +751,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab // tree. If we are overriding our own CD, we need to override all // our descendants. If we are not overriding our own CD, we are // also not overriding our descendants - if (isSubcomponentsOverridden()) { + if (isSubcomponentsOverriddenCD()) { overrideSubcomponentsCD(o); } @@ -777,28 +779,107 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * * @return whether the current mass, CG, and/or CD override overrides subcomponents as well. */ - public boolean isSubcomponentsOverridden() { + public boolean isSubcomponentsOverriddenMass() { mutex.verify(); - return overrideSubcomponents; + return overrideSubcomponentsMass; + } + + // TODO: delete no compatibility is needed anymore with OR 15.03 + public void setSubcomponentsOverridden(boolean override) { + setSubcomponentsOverriddenMass(override); + setSubcomponentsOverriddenCG(override); + setSubcomponentsOverriddenCD(override); } /** * Set whether the mass and/or CG override overrides all subcomponent values - * as well. See {@link #isSubcomponentsOverridden()} for details. + * as well. See {@link #isSubcomponentsOverriddenMass()} for details. * * @param override whether the mass and/or CG override overrides all subcomponent. */ - public void setSubcomponentsOverridden(boolean override) { + public void setSubcomponentsOverriddenMass(boolean override) { for (RocketComponent listener : configListeners) { - listener.setSubcomponentsOverridden(override); + listener.setSubcomponentsOverriddenMass(override); } - if (overrideSubcomponents == override) { + if (overrideSubcomponentsMass == override) { return; } checkState(); - overrideSubcomponents = override; + overrideSubcomponentsMass = override; + + fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + } + + /** + * Return whether the CG override overrides all subcomponent values + * as well. The default implementation is a normal getter/setter implementation, + * however, subclasses are allowed to override this behavior if some subclass + * always or never overrides subcomponents. In this case the subclass should + * also override {@link #isOverrideSubcomponentsEnabled()} to return + * false. + * + * @return whether the current CG override overrides subcomponents as well. + */ + public boolean isSubcomponentsOverriddenCG() { + mutex.verify(); + return overrideSubcomponentsCG; + } + + + /** + * Set whether the mass and/or CG override overrides all subcomponent values + * as well. See {@link #isSubcomponentsOverriddenCG()} for details. + * + * @param override whether the mass and/or CG override overrides all subcomponent. + */ + public void setSubcomponentsOverriddenCG(boolean override) { + for (RocketComponent listener : configListeners) { + listener.setSubcomponentsOverriddenCG(override); + } + + if (overrideSubcomponentsCG == override) { + return; + } + checkState(); + overrideSubcomponentsCG = override; + + fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + } + + /** + * Return whether the CD override overrides all subcomponent values + * as well. The default implementation is a normal getter/setter implementation, + * however, subclasses are allowed to override this behavior if some subclass + * always or never overrides subcomponents. In this case the subclass should + * also override {@link #isOverrideSubcomponentsEnabled()} to return + * false. + * + * @return whether the current CD override overrides subcomponents as well. + */ + public boolean isSubcomponentsOverriddenCD() { + mutex.verify(); + return overrideSubcomponentsCD; + } + + + /** + * Set whether the CD override overrides all subcomponent values + * as well. See {@link #isSubcomponentsOverriddenCD()} for details. + * + * @param override whether the CD override overrides all subcomponent. + */ + public void setSubcomponentsOverriddenCD(boolean override) { + for (RocketComponent listener : configListeners) { + listener.setSubcomponentsOverriddenCD(override); + } + + if (overrideSubcomponentsCD == override) { + return; + } + checkState(); + overrideSubcomponentsCD = override; overrideSubcomponentsCD(override); @@ -815,7 +896,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * If we are setting the override false, descend the component tree marking every * component as not overridden by ancestor. * If in the course of descending the tree we encounter a descendant whose direct - * CD override and overridesubcomponents flags are both true, descend from there + * CD override and overrideSubcomponentsCD flags are both true, descend from there * setting the ancestoroverride from that component * * @param override whether setting or clearing overrides @@ -827,7 +908,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab c.cdOverriddenByAncestor = override; - if (!override && c.isCDOverridden() && c.isSubcomponentsOverridden()) { + if (!override && c.isCDOverridden() && c.isSubcomponentsOverriddenCD()) { c.overrideSubcomponentsCD(true); } else { c.overrideSubcomponentsCD(override); @@ -2334,7 +2415,9 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab this.overrideCGX = src.overrideCGX; this.cgOverridden = src.cgOverridden; this.cdOverriddenByAncestor = src.cdOverriddenByAncestor; - this.overrideSubcomponents = src.overrideSubcomponents; + this.overrideSubcomponentsMass = src.overrideSubcomponentsMass; + this.overrideSubcomponentsCG = src.overrideSubcomponentsCG; + this.overrideSubcomponentsCD = src.overrideSubcomponentsCD; this.name = src.name; this.comment = src.comment; this.id = src.id; diff --git a/core/src/net/sf/openrocket/util/TestRockets.java b/core/src/net/sf/openrocket/util/TestRockets.java index 52fa2c96a..6ac2328bd 100644 --- a/core/src/net/sf/openrocket/util/TestRockets.java +++ b/core/src/net/sf/openrocket/util/TestRockets.java @@ -345,7 +345,8 @@ public class TestRockets { c.setMassOverridden(rnd.nextBoolean()); c.setOverrideCGX(rnd(0.2)); c.setOverrideMass(rnd(0.05)); - c.setSubcomponentsOverridden(rnd.nextBoolean()); + c.setSubcomponentsOverriddenMass(rnd.nextBoolean()); + c.setSubcomponentsOverriddenCG(rnd.nextBoolean()); if (c.isMassive()) { // Only massive components are drawn diff --git a/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java b/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java index 9ee1587ce..6c89ed6eb 100644 --- a/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java +++ b/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java @@ -81,7 +81,7 @@ public class MassCalculatorTest extends BaseTestCase { // if we use a mass override, setting to same mass, we should get same result AxialStage sustainer = (AxialStage) rocket.getChild(0); - sustainer.setSubcomponentsOverridden(true); + sustainer.setSubcomponentsOverriddenMass(true); sustainer.setMassOverridden(true); sustainer.setOverrideMass(actualRocketDryMass); @@ -219,7 +219,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(expCMx, actualRocketDryCM.x, EPSILON); } - boosterStage.setSubcomponentsOverridden(true); + boosterStage.setSubcomponentsOverriddenCG(true); boosterStage.setCGOverridden(true); boosterStage.setOverrideCGX(0.0); @@ -260,7 +260,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(0.05, actualRocketDryCM.x, EPSILON); } - sustainerStage.setSubcomponentsOverridden(true); + sustainerStage.setSubcomponentsOverriddenMass(true); sustainerStage.setMassOverridden(true); sustainerStage.setOverrideMass(0.001); // something small, but not zero @@ -302,7 +302,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(0.10, actualStructure.cm.x, EPSILON); } - boosterStage.setSubcomponentsOverridden(true); + boosterStage.setSubcomponentsOverriddenMass(true); boosterStage.setMassOverridden(true); boosterStage.setOverrideMass(0.001); // something small, but not zero @@ -346,7 +346,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(expCMx, actualRocketDryCM.x, EPSILON); } - boosterBody.setSubcomponentsOverridden(false); + boosterBody.setSubcomponentsOverriddenCG(false); boosterBody.setCGOverridden(true); boosterBody.setOverrideCGX(0.0); @@ -395,7 +395,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(expCMx, actualRocketDryCM.x, EPSILON); } - boosterBody.setSubcomponentsOverridden(false); + boosterBody.setSubcomponentsOverriddenMass(false); boosterBody.setMassOverridden(true); boosterBody.setOverrideMass(0.001); @@ -409,7 +409,7 @@ public class MassCalculatorTest extends BaseTestCase { assertEquals(0.06976699, actualRocketDryCM.x, EPSILON); } - boosterBody.setSubcomponentsOverridden(true); // change. Also, this body lacks subcomponents. + boosterBody.setSubcomponentsOverriddenMass(true); // change. Also, this body lacks subcomponents. boosterBody.setMassOverridden(true); // repeat boosterBody.setOverrideMass(0.001); // repeat @@ -973,9 +973,10 @@ public class MassCalculatorTest extends BaseTestCase { final AxialStage coreStage = (AxialStage) rocket.getChild(1); final ParallelStage boosters = (ParallelStage) coreStage.getChild(0).getChild(0); final double overrideMass = 0.5; - boosters.setSubcomponentsOverridden(true); + boosters.setSubcomponentsOverriddenMass(true); boosters.setMassOverridden(true); boosters.setOverrideMass(overrideMass); + boosters.setSubcomponentsOverriddenCG(true); boosters.setCGOverridden(true); boosters.setOverrideCGX(6.0); @@ -1140,7 +1141,7 @@ public class MassCalculatorTest extends BaseTestCase { fins.setName("podFins"); fins.setThickness(0.01); fins.setMassOverridden(true); fins.setOverrideMass(0.02835); - fins.setSubcomponentsOverridden(false); + fins.setSubcomponentsOverriddenMass(false); fins.setAxialOffset(-0.01); fins.setAxialMethod(AxialMethod.BOTTOM); podBody.addChild(fins); @@ -1207,12 +1208,12 @@ public class MassCalculatorTest extends BaseTestCase { // if we use a mass override, setting to same mass, we should get same result AxialStage sustainerRef = (AxialStage) rocketRef.getChild(0); - sustainerRef.setSubcomponentsOverridden(true); + sustainerRef.setSubcomponentsOverriddenMass(true); sustainerRef.setMassOverridden(true); sustainerRef.setOverrideMass(rocketDryMassRef); AxialStage sustainer = (AxialStage) rocket.getChild(0); - sustainer.setSubcomponentsOverridden(true); + sustainer.setSubcomponentsOverriddenMass(true); sustainer.setMassOverridden(true); sustainer.setOverrideMass(rocketDryMass); diff --git a/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java b/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java index f8e343832..8e17dfa71 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/FreeformFinSetTest.java @@ -54,7 +54,8 @@ public class FreeformFinSetTest extends BaseTestCase { sourceSet.setMaterial(Material.newMaterial(Type.BULK, "test-material", 0.1, true)); sourceSet.setOverrideCGX(0.012); sourceSet.setOverrideMass(0.0123); - sourceSet.setSubcomponentsOverridden(true); + sourceSet.setSubcomponentsOverriddenMass(true); + sourceSet.setSubcomponentsOverriddenCG(true); sourceSet.setAxialMethod(AxialMethod.ABSOLUTE); sourceSet.setAxialOffset(0.1); sourceSet.setTabHeight(0.01); @@ -196,7 +197,8 @@ public class FreeformFinSetTest extends BaseTestCase { } assertEquals(0.012, finSet.getOverrideCGX(), EPSILON); assertEquals(0.0123, finSet.getOverrideMass(), EPSILON); - assertTrue(finSet.isSubcomponentsOverridden()); + assertTrue(finSet.isSubcomponentsOverriddenMass()); + assertTrue(finSet.isSubcomponentsOverriddenCG()); assertEquals(AxialMethod.ABSOLUTE, finSet.getAxialMethod()); assertEquals(0.1, finSet.getAxialOffset(), EPSILON); @@ -232,7 +234,8 @@ public class FreeformFinSetTest extends BaseTestCase { } assertEquals(0.012, finSet.getOverrideCGX(), EPSILON); assertEquals(0.0123, finSet.getOverrideMass(), EPSILON); - assertTrue(finSet.isSubcomponentsOverridden()); + assertTrue(finSet.isSubcomponentsOverriddenMass()); + assertTrue(finSet.isSubcomponentsOverriddenCG()); assertEquals(AxialMethod.ABSOLUTE, finSet.getAxialMethod()); assertEquals(0.1, finSet.getAxialOffset(), EPSILON); diff --git a/core/test/net/sf/openrocket/rocketcomponent/OverrideTest.java b/core/test/net/sf/openrocket/rocketcomponent/OverrideTest.java index 36ff91df0..aaad470bb 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/OverrideTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/OverrideTest.java @@ -65,19 +65,19 @@ public class OverrideTest extends BaseTestCase { // We start by just checking the override flags // Initially no overrides assertFalse(sustainer.isCDOverridden()); - assertFalse(sustainer.isSubcomponentsOverridden()); + assertFalse(sustainer.isSubcomponentsOverriddenCD()); assertFalse(sustainer.isCDOverriddenByAncestor()); assertFalse(bodytube.isCDOverridden()); - assertFalse(bodytube.isSubcomponentsOverridden()); + assertFalse(bodytube.isSubcomponentsOverriddenCD()); assertFalse(bodytube.isCDOverriddenByAncestor()); assertFalse(finset.isCDOverridden()); - assertFalse(finset.isSubcomponentsOverridden()); + assertFalse(finset.isSubcomponentsOverriddenCD()); assertFalse(finset.isCDOverriddenByAncestor()); // Override sustainer CD and subcomponents - sustainer.setSubcomponentsOverridden(true); + sustainer.setSubcomponentsOverriddenCD(true); sustainer.setCDOverridden(true); sustainer.setOverrideCD(0.5); @@ -87,7 +87,7 @@ public class OverrideTest extends BaseTestCase { // Set body tube to override subcomponents, override its CD; it's still // overridden by ancestor bodytube.setCDOverridden(true); - bodytube.setSubcomponentsOverridden(true); + bodytube.setSubcomponentsOverriddenCD(true); bodytube.setOverrideCD(0.25); assertTrue(bodytube.isCDOverriddenByAncestor()); @@ -103,7 +103,7 @@ public class OverrideTest extends BaseTestCase { assertEquals(sustainer.getOverrideCD(), forces.getCD(), MathUtil.EPSILON); // Turn off sustainer subcomponents override; body tube and nose cone aren't overridden by ancestor but fin set is - sustainer.setSubcomponentsOverridden(false); + sustainer.setSubcomponentsOverriddenCD(false); // CD of rocket should be overridden CD of sustainer plus body tube plus calculated CD of nose cone Map forceMap = calc.getForceAnalysis(configuration, conditions, warnings); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java index 628d54f38..de4777116 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java @@ -4,6 +4,7 @@ package net.sf.openrocket.gui.configdialog; import java.awt.Color; import java.awt.Component; import java.awt.Container; +import java.awt.Font; import java.awt.event.*; import java.util.ArrayList; import java.util.Iterator; @@ -236,7 +237,7 @@ public class RocketComponentConfig extends JPanel { } for (RocketComponent c = component.getParent(); c != null; c = c.getParent()) { - if (c.isMassOverridden() && c.isSubcomponentsOverridden()) { + if (c.isMassOverridden() && c.isSubcomponentsOverriddenMass()) { overridetext = trans.get("RocketCompCfg.lbl.overriddenby") + " " + c.getName() + ")"; } } @@ -359,14 +360,28 @@ public class RocketComponentConfig extends JPanel { BasicSlider bs; // OVERRIDE MASS ---------------------------------- - + JPanel checkboxes = new JPanel(new MigLayout("inset 0")); bm = new BooleanModel(component, "MassOverridden"); check = new JCheckBox(bm); //// Override mass: check.setText(trans.get("RocketCompCfg.checkbox.Overridemass")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.Overridemass.ttip")); - panel.add(check, "growx 1, gapright 20lp"); + checkboxes.add(check, "wrap"); order.add(check); + + ////// Override subcomponents + BooleanModel bmSubcomp = new BooleanModel(component, "SubcomponentsOverriddenMass"); + check = new JCheckBox(bmSubcomp); + check.setText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents")); + Font smallFont = check.getFont(); + smallFont = smallFont.deriveFont(smallFont.getSize2D() - 1); + check.setFont(smallFont); + check.setToolTipText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents.Mass.ttip")); + bm.addEnableComponent(check, true); + checkboxes.add(check, "gapleft 25lp, wrap"); + order.add(check); + + panel.add(checkboxes, "growx 1, gapright 20lp"); DoubleModel m = new DoubleModel(component, "OverrideMass", UnitGroup.UNITS_MASS, 0); @@ -383,18 +398,30 @@ public class RocketComponentConfig extends JPanel { bs = new BasicSlider(m.getSliderModel(0, 0.03, 1.0)); bm.addEnableComponent(bs); panel.add(bs, "growx 5, w 100lp, wrap"); - + // END OVERRIDE MASS ---------------------------------- // OVERRIDE CG ---------------------------------- - + checkboxes = new JPanel(new MigLayout("inset 0")); bm = new BooleanModel(component, "CGOverridden"); check = new JCheckBox(bm); //// Override center of gravity:" check.setText(trans.get("RocketCompCfg.checkbox.Overridecenterofgrav")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.Overridecenterofgrav.ttip")); - panel.add(check, "growx 1, gapright 20lp"); + checkboxes.add(check, "wrap"); order.add(check); + + ////// Override subcomponents + bmSubcomp = new BooleanModel(component, "SubcomponentsOverriddenCG"); + check = new JCheckBox(bmSubcomp); + check.setText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents")); + check.setFont(smallFont); + check.setToolTipText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents.CG.ttip")); + bm.addEnableComponent(check, true); + checkboxes.add(check, "gapleft 25lp, wrap"); + order.add(check); + + panel.add(checkboxes, "growx 1, gapright 20lp"); m = new DoubleModel(component, "OverrideCGX", UnitGroup.UNITS_LENGTH, 0); // Calculate suitable length for slider @@ -441,46 +468,47 @@ public class RocketComponentConfig extends JPanel { bs = new BasicSlider(m.getSliderModel(new DoubleModel(0), length)); bm.addEnableComponent(bs); panel.add(bs, "growx 5, w 100lp, wrap"); - // END OVERRIDE CG --------------------------------------------------- - // BEGIN OVERRIDE CD ------------------------------------------ + // BEGIN OVERRIDE CD ------------------------------------------ + checkboxes = new JPanel(new MigLayout("inset 0")); bm = new BooleanModel(component, "CDOverridden"); check = new JCheckBox(bm); //// Override coefficient of drag: check.setText(trans.get("RocketCompCfg.checkbox.SetDragCoeff")); check.setToolTipText(trans.get("RocketCompCfg.checkbox.SetDragCoeff.ttip")); - panel.add(check, "growx 1, gapright 20lp"); + checkboxes.add(check, "wrap"); order.add(check); + + ////// Override subcomponents + bmSubcomp = new BooleanModel(component, "SubcomponentsOverriddenCD"); + check = new JCheckBox(bmSubcomp); + check.setText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents")); + check.setFont(smallFont); + check.setToolTipText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents.CD.ttip")); + bm.addEnableComponent(check, true); + checkboxes.add(check, "gapleft 25lp, wrap"); + order.add(check); + + panel.add(checkboxes, "growx 1, gapright 20lp"); m = new DoubleModel(component, "OverrideCD", UnitGroup.UNITS_COEFFICIENT, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); bm.addEnableComponent(spin, true); - panel.add(spin, "growx 1"); + panel.add(spin, "top, growx 1"); order.add(((SpinnerEditor) spin.getEditor()).getTextField()); bs = new BasicSlider(m.getSliderModel(-1.0, 1.0)); bm.addEnableComponent(bs); - panel.add(bs, "skip, growx 5, w 100lp, wrap"); + panel.add(bs, "top, skip, growx 5, w 100lp, wrap"); // END OVERRIDE CD -------------------------------------------------- - // BEGIN OVERRIDE SUBCOMPONENTS -------------------------------------------------- - - bm = new BooleanModel(component, "SubcomponentsOverridden"); - check = new JCheckBox(bm); - //// Override mass, CG, and CD of all subcomponents - check.setText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents")); - check.setToolTipText(trans.get("RocketCompCfg.checkbox.OverrideSubcomponents.ttip")); - panel.add(check, "spanx, wrap 35lp"); - - // END OVERRIDE SUBCOMPONENTS -------------------------------------------------- - // OVERRIDE MASS, CG DOESN'T INCLUDE MOTORS -------------------------------------------------- panel.add(new StyledLabel(trans.get("RocketCompCfg.lbl.longB1") + //// The center of gravity is measured from the front end of the