Merge branch 'unstable' into issue-1532

This commit is contained in:
SiboVG 2022-08-14 11:11:16 +02:00
commit bd1e9983b1
127 changed files with 2617 additions and 1117 deletions

View File

@ -17,6 +17,7 @@
<classpathentry kind="lib" path="lib/javax.inject.jar"/>
<classpathentry kind="lib" path="lib/javax.json-1.1.3.jar"/>
<classpathentry kind="lib" path="lib/javax.json-api-1.1.3.jar"/>
<classpathentry kind="lib" path="lib/javax.activation-api.2.3.1.jar"/>
<classpathentry kind="lib" path="lib/aopalliance.jar"/>
<classpathentry kind="lib" path="lib/commonmark-0.19.0.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-1.7.30.jar"/>

View File

@ -270,5 +270,32 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/js-scriptengine-22.1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/js-22.1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/graal-sdk-22.1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>

Binary file not shown.

BIN
core/lib/icu4j-71.1.jar Normal file

Binary file not shown.

BIN
core/lib/js-22.1.0.1.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
core/lib/yasson-1.0.2.jar Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

View File

@ -294,6 +294,8 @@ pref.dlg.lbl.PositiontoinsertStages = Position to insert new stages:
pref.dlg.lbl.Confirmdeletion = Confirm deletion of simulations.
pref.dlg.checkbox.Runsimulations = Run out-dated simulations when you open the simulation tab.
pref.dlg.checkbox.Updateestimates = Update estimated flight parameters in design window
pref.dlg.checkbox.Markers = Only show pod set/booster markers when the pod set/booster is selected
pref.dlg.checkbox.Markers.ttip = <html>If checked, pod set/booster markers will only be shown when the pod set/booster is selected.<br>If unchecked, pod set/booster markers will always be shown.</html>
pref.dlg.checkbox.AlwaysOpenLeftmost = Always open leftmost tab when opening a component edit dialog
pref.dlg.checkbox.AlwaysOpenLeftmost.ttip = <html>If checked, a component edit dialog will always pop up with the first tab selected.<br>If unchecked, the previous selected tab will be used.</html>
pref.dlg.lbl.User-definedthrust = User-defined thrust curves:
@ -1050,7 +1052,10 @@ LaunchLugCfg.tab.Generalprop = General properties
! RailButtonConfig
RailBtnCfg.lbl.OuterDiam = Outer Diameter:
RailBtnCfg.lbl.TotalHeight = Total Height
RailBtnCfg.lbl.InnerDiam = Inner Diameter:
RailBtnCfg.lbl.TotalHeight = Total Height:
RailBtnCfg.lbl.BaseHeight = Base Height:
RailBtnCfg.lbl.FlangeHeight = Flange Height:
RailBtnCfg.lbl.Angle = Rotation:
RailBtnCfg.lbl.PosRelativeTo = Position relative to:
RailBtnCfg.lbl.Plus = plus
@ -1373,14 +1378,13 @@ main.menu.edit.editpreset= Edit Component Preset File
main.menu.edit.preferences = Preferences
main.menu.edit.preferences.desc = Setup the application preferences
main.menu.analyze = Tools
main.menu.analyze.desc = Rocket analysis
main.menu.analyze.componentAnalysis = Component analysis
main.menu.analyze.componentAnalysis.desc = Analyze the rocket components separately
main.menu.analyze.optimization = Rocket optimization
main.menu.analyze.optimization.desc = General rocket design optimization
main.menu.analyze.customExpressions = Custom expressions
main.menu.analyze.customExpressions.desc = Define new flight data types by writing custom mathematical expressions
main.menu.tools = Tools
main.menu.tools.componentAnalysis = Component analysis
main.menu.tools.componentAnalysis.desc = Analyze the rocket components separately
main.menu.tools.optimization = Rocket optimization
main.menu.tools.optimization.desc = General rocket design optimization
main.menu.tools.customExpressions = Custom expressions
main.menu.tools.customExpressions.desc = Define new flight data types by writing custom mathematical expressions
main.menu.help = Help
main.menu.help.desc = Information about OpenRocket
@ -2072,8 +2076,10 @@ CustomFinImport.error.badimage = Could not deduce fin shape from image.
CustomFinImport.description = The image will be converted internally to black and white image (black for the fin), so make sure you use a solid dark color for the fin, and white or a light color for the background. The fin must be touching the bottom of the image, which is the base of the fin.
PresetModel.lbl.select = Select preset
PresetModel.lbl.database = From database\u2026
PresetModel.combo.ttip = <html>Select a preset model from a list of favorites (selected in the component preset dialog),<br>or select 'Custom' when no preset is required.</html>
PresetModel.lbl.custompreset = Custom
PresetModel.lbl.partsLib = Parts Library
PresetModel.lbl.partsLib.ttip = Select a preset model for this rocket component from a library of parts.
DecalModel.lbl.select = <none>
DecalModel.lbl.choose = From file\u2026
@ -2095,7 +2101,7 @@ ComponentPresetChooserDialog.menu.sortDesc = Sort Descending
ComponentPresetChooserDialog.menu.units = Units
ComponentPresetChooserDialog.checkbox.showAllCompatible = Show all compatible
ComponentPresetChooserDialog.checkbox.showLegacyCheckBox = Show Legacy Database
ComponentPresetChooserDialog.lbl.favorites = Select to add preset to drop-down menu
ComponentPresetChooserDialog.lbl.favorites = Check to add preset to the preset drop-down menu in the component edit dialog<br>Directly apply a preset by double-clicking it or by selecting it and closing this window.
table.column.Favorite = Favorite
table.column.Legacy = Legacy
table.column.Manufacturer = Manufacturer
@ -2112,19 +2118,23 @@ table.column.AftShoulderDiameter = Aft Shoulder Diameter
table.column.ForeShoulderLength = Fore Shoulder Length
table.column.ForeShoulderDiameter = Fore Shoulder Diameter
table.column.ForeOuterDiameter = Fore Outer Diameter
table.column.StandoffHeight = Standoff Height
table.column.BaseHeight = Base Height
table.column.FlangeHeight = Flange Height
table.column.ScrewHeight = Screw Height
table.column.Shape = Shape
table.column.Material = Material
table.column.Finish = Finish
table.column.Thickness = Thickness
table.column.Filled = Filled
table.column.Mass = Mass
table.column.ScrewMass = Screw Mass
table.column.NutMass = Nut Mass
table.column.Diameter = Diameter
table.column.Sides = Sides
table.column.LineCount = Line Count
table.column.LineLength = Line Length
table.column.LineMaterial = Line Material
table.column.CD = Drag Coefficient
! Edit Decal Dialog
EditDecalDialog.title = Edit decal

View File

@ -1004,12 +1004,11 @@ main.menu.edit.delete = Smazat
main.menu.edit.preferences = Nastavení
main.menu.edit.preferences.desc = Nastavení aplikace
main.menu.analyze = Anal\u017Eýza
main.menu.analyze.desc = Analýza rakety
main.menu.analyze.componentAnalysis = Analýza komponent
main.menu.analyze.componentAnalysis.desc = Analyzuj cásti rakety samostatne
main.menu.analyze.optimization = Optimalizace rakety
main.menu.analyze.optimization.desc = Obecný návrh optimalizace rakety
main.menu.tools = Anal\u017Eýza
main.menu.tools.componentAnalysis = Analýza komponent
main.menu.tools.componentAnalysis.desc = Analyzuj cásti rakety samostatne
main.menu.tools.optimization = Optimalizace rakety
main.menu.tools.optimization.desc = Obecný návrh optimalizace rakety
main.menu.help = Pomoc
main.menu.help.desc = Informace o programu OpenRocket
@ -1587,8 +1586,8 @@ CustomFinImport.error.badimage = Nemohu vyvodit tvar stabiliz
CustomFinImport.description = Obrázek bude zmenen na cernobílý \n(cerná pro stabilizátor), ujistete se prosím, \u017Ee jste pou\u017Eily cernou barvu na stabilizátor \na bílou nebo svetlou barvu na pozadí. Stabilizátor \nse musí dotýkat steny obrázku, která predstavuje uchycení pro stabilizátor.
PresetModel.lbl.select = Výber predvolby:
PresetModel.lbl.database = Z databáze...
PresetModel.lbl.custompreset = Vlastní
PresetModel.lbl.partsLib = Knihovna díl?
! Component Preset Chooser Dialog

View File

@ -1061,12 +1061,11 @@ main.menu.edit.delete = L
main.menu.edit.preferences = Einstellungen
main.menu.edit.preferences.desc = Einstellungen der Anwenung ändern
main.menu.analyze = Analysieren
main.menu.analyze.desc = Rakete analysieren
main.menu.analyze.componentAnalysis = Komponente analysieren
main.menu.analyze.componentAnalysis.desc = Komponenten der Rakete einzeln analysieren
main.menu.analyze.optimization = Rocket optimization
main.menu.analyze.optimization.desc = General rocket design optimization
main.menu.tools = Analysieren
main.menu.tools.componentAnalysis = Komponente analysieren
main.menu.tools.componentAnalysis.desc = Komponenten der Rakete einzeln analysieren
main.menu.tools.optimization = Rocket optimization
main.menu.tools.optimization.desc = General rocket design optimization
main.menu.help = Hilfe
main.menu.help.desc = Informationen über OpenRocket
@ -1645,8 +1644,8 @@ CustomFinImport.error.badimage = Konnte keine Leitwerksform aus dem Bild erzeuge
CustomFinImport.description = Das Bild wird intern in ein Schwarz-Weiß-Bild konvertiert (Leitwerk: schwarz). Bitte sicherstellen, dass das Leitwerk in einer dichten, dunklen Farbe ist, während der Hintergrund weiß oder sehr hell sein sollte. Das Leitwerk muss das untere Bildende berühren, da dies die Verbindungsstelle zur Rakete wird.
PresetModel.lbl.select = Voreinstellung auswählen:
PresetModel.lbl.database = Aus Datenbank...
PresetModel.lbl.custompreset = Benutzerdefiniert
PresetModel.lbl.partsLib = Teile-Bibliothek
! Component Preset Chooser Dialog

View File

@ -737,8 +737,8 @@ PreferencesDialog.languages.default = Idioma por defecto
PreferencesDialog.lbl.language = Idioma de la interfaz:
PreferencesDialog.lbl.languageEffect = El idioma cambiar\u00e1 la pr\u00f3xima vez que abra OpenRocket.
PresetModel.lbl.database = Desde la Base de Datos...
PresetModel.lbl.select = Prefabricado
PresetModel.lbl.custompreset = Personalizado
PresetModel.lbl.partsLib = Biblioteca de piezas
PrintDialog.but.previewAndPrint = Vista previa e Imprimir
PrintDialog.checkbox.showByStage = Mostrar por etapas
@ -1429,14 +1429,13 @@ FileHelper.IMAGES = Archivos de imagen
! General file type names
FileHelper.PDF_FILTER = Archivos PDF
main.menu.analyze = Analizar
main.menu.analyze.componentAnalysis = An\u00e1lisis de los componentes
main.menu.analyze.componentAnalysis.desc = Analiza los componentes del cohete por separado
main.menu.analyze.customExpressions = Expresiones personalizadas
main.menu.analyze.customExpressions.desc = Defina nuevos tipos de datos escribiendo expresiones matem\u00e1ticas personalizadas
main.menu.analyze.desc = An\u00e1lisis del cohete
main.menu.analyze.optimization = Optimizaci\u00f3n del dise\u00f1o
main.menu.analyze.optimization.desc = Optimizaci\u00f3n global del dise\u00f1o del cohete
main.menu.tools = Analizar
main.menu.tools.componentAnalysis = An\u00e1lisis de los componentes
main.menu.tools.componentAnalysis.desc = Analiza los componentes del cohete por separado
main.menu.tools.customExpressions = Expresiones personalizadas
main.menu.tools.customExpressions.desc = Defina nuevos tipos de datos escribiendo expresiones matem\u00e1ticas personalizadas
main.menu.tools.optimization = Optimizaci\u00f3n del dise\u00f1o
main.menu.tools.optimization.desc = Optimizaci\u00f3n global del dise\u00f1o del cohete
main.menu.debug = Recuperaci\u00f3n
main.menu.debug.createtestrocket = Crear una prueba de modelo
main.menu.debug.whatisthismenu = \u00bfQue es este men\u00fa?

View File

@ -729,8 +729,8 @@ PreferencesDialog.languages.default = Valeur syst\u00E8me par d\u00E9faut
PreferencesDialog.lbl.language = Langue du programme:
PreferencesDialog.lbl.languageEffect = La langue sera chang\u00E9e apr\u00E8s avoir red\u00E9marr\u00E9 OpenRocket.
PresetModel.lbl.database = A partir d'une base de donn\u00E9es...
PresetModel.lbl.select = Choisir une pi\u00E8ce pr\u00E9d\u00E9finie:
PresetModel.lbl.custompreset = Personnalisé
PresetModel.lbl.partsLib = Biblioth\u00E8que de pi\u00E8ces
PrintDialog.but.previewAndPrint = Pr\u00E9-visualiser et imprimer
PrintDialog.checkbox.showByStage = Montrer par \u00E9tage
@ -1423,14 +1423,13 @@ FileHelper.IMAGES = Fichiers Image
! General file type names
FileHelper.PDF_FILTER = fichier PDF
main.menu.analyze = Analyse
main.menu.analyze.componentAnalysis = Analyse des Pi\u00E8ces
main.menu.analyze.componentAnalysis.desc = Analyse s\u00E9par\u00E9e des pi\u00E8ces de la fus\u00E9e
main.menu.analyze.customExpressions = Expressions personnalis\u00E9es
main.menu.analyze.customExpressions.desc = D\u00E9fini de nouveaux type de donn\u00E9es de vol en \u00E9crivant des expressions math\u00E9matique personnalis\u00E9es
main.menu.analyze.desc = Analyses de la fus\u00E9e
main.menu.analyze.optimization = Optimisation de la fus\u00E9e
main.menu.analyze.optimization.desc = Optimisation g\u00E9n\u00E9rale de la fus\u00E9e
main.menu.tools = Analyse
main.menu.tools.componentAnalysis = Analyse des Pi\u00E8ces
main.menu.tools.componentAnalysis.desc = Analyse s\u00E9par\u00E9e des pi\u00E8ces de la fus\u00E9e
main.menu.tools.customExpressions = Expressions personnalis\u00E9es
main.menu.tools.customExpressions.desc = D\u00E9fini de nouveaux type de donn\u00E9es de vol en \u00E9crivant des expressions math\u00E9matique personnalis\u00E9es
main.menu.tools.optimization = Optimisation de la fus\u00E9e
main.menu.tools.optimization.desc = Optimisation g\u00E9n\u00E9rale de la fus\u00E9e
main.menu.debug = Debug
main.menu.debug.createtestrocket = Cr\u00E9er une fus\u00E9e test
main.menu.debug.whatisthismenu = Quel est ce menu?

View File

@ -1065,12 +1065,11 @@ main.menu.edit.delete = Cancella
main.menu.edit.preferences = Preferenze
main.menu.edit.preferences.desc = Imposta le preferenze dell'applicazione
main.menu.analyze = Analizza
main.menu.analyze.desc = Analisi del razzo
main.menu.analyze.componentAnalysis = Analizza componente
main.menu.analyze.componentAnalysis.desc = Analizza ogni componente del razzo separatamente
main.menu.analyze.optimization = Ottimizzazione del razzo
main.menu.analyze.optimization.desc = Ottimizzazioni generali sul disegno del razzo
main.menu.tools = Analizza
main.menu.tools.componentAnalysis = Analizza componente
main.menu.tools.componentAnalysis.desc = Analizza ogni componente del razzo separatamente
main.menu.tools.optimization = Ottimizzazione del razzo
main.menu.tools.optimization.desc = Ottimizzazioni generali sul disegno del razzo
main.menu.help = Aiuto
main.menu.help.desc = Informazioni su OpenRocket
@ -1651,8 +1650,8 @@ CustomFinImport.error.badimage = Non riesco a capire la forma della pinna dall
CustomFinImport.description = L'immagine sar\u00e0 convertita in bianco e nero internamente (nero per le pinne), cos\u00ec assicurati di usare un nero pieno per le pinne e bianco, o colore chiaro, per lo sfondo. La pinna ndeve toccare il fondo dell'immagine, che \u00e8 la base della pinna.
PresetModel.lbl.select = Seleziona precaricati:
PresetModel.lbl.database = Da database...
PresetModel.lbl.custompreset = Personalizzato
PresetModel.lbl.partsLib = Libreria di parti
! Component Preset Chooser Dialog

View File

@ -1097,14 +1097,13 @@ main.menu.edit.editpreset = Component Preset File\u306E\u7DE8\u96C6
main.menu.edit.preferences = \u8A2D\u5B9A
main.menu.edit.preferences.desc = \u30A2\u30D7\u30EA\u306E\u8A2D\u5B9A\u3092\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7
main.menu.analyze = \u89E3\u6790
main.menu.analyze.desc = \u30ED\u30B1\u30C3\u30C8\u89E3\u6790
main.menu.analyze.componentAnalysis = \u90E8\u54C1\u89E3\u6790
main.menu.analyze.componentAnalysis.desc = \u90E8\u54C1\u3092\u5206\u3051\u3066\u89E3\u6790
main.menu.analyze.optimization = \u30ED\u30B1\u30C3\u30C8\u6700\u9069\u5316
main.menu.analyze.optimization.desc = \u5168\u4F53\u3092\u6700\u9069\u5316
main.menu.analyze.customExpressions = \u30AB\u30B9\u30BF\u30E0\u5F0F
main.menu.analyze.customExpressions.desc = \u65B0\u3057\u3044\u30D5\u30E9\u30A4\u30C8\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u3092\u30AB\u30B9\u30BF\u30E0\u3057\u305F\u6570\u5F0F\u3067\u5B9A\u7FA9
main.menu.tools = \u89E3\u6790
main.menu.tools.componentAnalysis = \u90E8\u54C1\u89E3\u6790
main.menu.tools.componentAnalysis.desc = \u90E8\u54C1\u3092\u5206\u3051\u3066\u89E3\u6790
main.menu.tools.optimization = \u30ED\u30B1\u30C3\u30C8\u6700\u9069\u5316
main.menu.tools.optimization.desc = \u5168\u4F53\u3092\u6700\u9069\u5316
main.menu.tools.customExpressions = \u30AB\u30B9\u30BF\u30E0\u5F0F
main.menu.tools.customExpressions.desc = \u65B0\u3057\u3044\u30D5\u30E9\u30A4\u30C8\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7\u3092\u30AB\u30B9\u30BF\u30E0\u3057\u305F\u6570\u5F0F\u3067\u5B9A\u7FA9
main.menu.help = \u30D8\u30EB\u30D7
main.menu.help.desc = OpenRocket\u306B\u3064\u3044\u3066\u306E\u60C5\u5831
@ -1713,8 +1712,8 @@ CustomFinImport.error.badimage = \u753B\u50CF\u304B\u3089\u30D5\u30A3\u30F3\u5F
CustomFinImport.description = \u753B\u50CF\u306F\u5185\u90E8\u3067\u767D\u80CC\u666F\u3068\u9ED2\u7DDA\u306B\u5909\u63DB\u3055\u308C\u307E\u3059\u3002\u306A\u306E\u3067\u30D5\u30A3\u30F3\u306B\u306F\u6697\u3044\u8272\u306E\u5B9F\u7DDA\u3001\u80CC\u666F\u306B\u306F\u767D\u304B\u660E\u308B\u3044\u8272\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30D5\u30A3\u30F3\u306F\u753B\u50CF\u306E\u5E95\u9762\u306B\u63A5\u3057\u3066\u3044\u306A\u304F\u3066\u306F\u3044\u3051\u307E\u305B\u3093\u3001\u3053\u308C\u306F\u30D5\u30A3\u30F3\u306E\u5E95\u9762\u306B\u306A\u308A\u307E\u3059\u3002
PresetModel.lbl.select = Select preset
PresetModel.lbl.database = From database...
PresetModel.lbl.custompreset = \u30ab\u30b9\u30bf\u30e0
PresetModel.lbl.partsLib = \u30d1\u30fc\u30c4\u30e9\u30a4\u30d6\u30e9\u30ea\u30fc
! Component Preset Chooser Dialog

View File

@ -1274,14 +1274,13 @@ main.menu.edit.editpreset= Bewerk Component Preset bestand
main.menu.edit.preferences = Voorkeuren
main.menu.edit.preferences.desc = Stel de programma voorkeuren in
main.menu.analyze = Tools
main.menu.analyze.desc = Raket-analyses
main.menu.analyze.componentAnalysis = Onderdeel-analyses
main.menu.analyze.componentAnalysis.desc = Analyseer de raketonderdelen afzonderlijk
main.menu.analyze.optimization = Raket-optimalisatie
main.menu.analyze.optimization.desc = Algemene optimalisatie van raketontwerp
main.menu.analyze.customExpressions = Aangepaste uitdrukkingen
main.menu.analyze.customExpressions.desc = Definieer nieuwe vluchtdatatypes door aangepaste wiskundige uitdrukkingen te schrijven
main.menu.tools = Tools
main.menu.tools.componentAnalysis = Onderdeel-analyses
main.menu.tools.componentAnalysis.desc = Analyseer de raketonderdelen afzonderlijk
main.menu.tools.optimization = Raket-optimalisatie
main.menu.tools.optimization.desc = Algemene optimalisatie van raketontwerp
main.menu.tools.customExpressions = Aangepaste uitdrukkingen
main.menu.tools.customExpressions.desc = Definieer nieuwe vluchtdatatypes door aangepaste wiskundige uitdrukkingen te schrijven
main.menu.help = Help
main.menu.help.desc = Informatie over OpenRocket
@ -1967,8 +1966,8 @@ CustomFinImport.error.badimage = Kon de vorm van de vin niet afleiden uit het be
CustomFinImport.description = De afbeelding wordt intern geconverteerd naar een zwart-wit afbeelding (zwart voor de vin), dus zorg ervoor dat je een effen donkere kleur gebruikt voor de vin, en wit of een lichte kleur voor de achtergrond. De vin moet de onderkant van het beeld raken, dat is de basis van de vin.
PresetModel.lbl.select = Selecteer preset
PresetModel.lbl.database = Uit databank...
PresetModel.lbl.custompreset = Aangepast
PresetModel.lbl.partsLib = Onderdelenbibliotheek
DecalModel.lbl.select = <geen>
DecalModel.lbl.choose = Van bestand...
@ -2003,7 +2002,7 @@ table.column.AftShoulderDiameter = Achteste Schouderdiameter
table.column.ForeShoulderLength = Voorste Schouderlengte
table.column.ForeShoulderDiameter = Voorste Schouderdiameter
table.column.ForeOuterDiameter = Voorste Buitendiameter
table.column.StandoffHeight = Standoff Hoogte
table.column.BaseHeight = Standoff Hoogte
table.column.FlangeHeight = Flens Hoogte
table.column.Shape = Vorm
table.column.Material = Materiaal

View File

@ -1006,12 +1006,11 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
main.menu.edit.preferences = Ustawienia
main.menu.edit.preferences.desc = Edytuj ustawienia programu
main.menu.analyze = Analiza
main.menu.analyze.desc = Analiza rakiety
main.menu.analyze.componentAnalysis = Analiza cz\u0119\u015Bci
main.menu.analyze.componentAnalysis.desc = Analizuj oddzielnie poszczególne cz\u0119\u015Bci sk\u0142adóe rakiety
main.menu.analyze.optimization = Optymalizacja rakiety
main.menu.analyze.optimization.desc = Ogólna optymalizacja projektu rakiety
main.menu.tools = Analiza
main.menu.tools.componentAnalysis = Analiza cz\u0119\u015Bci
main.menu.tools.componentAnalysis.desc = Analizuj oddzielnie poszczególne cz\u0119\u015Bci sk\u0142adóe rakiety
main.menu.tools.optimization = Optymalizacja rakiety
main.menu.tools.optimization.desc = Ogólna optymalizacja projektu rakiety
main.menu.help = Pomoc
main.menu.help.desc = Informacje o programie OpenRocket
@ -1592,8 +1591,8 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
CustomFinImport.description = Obraz zostanie automatycznie zamieniony na czarno-bia\u0142y (statecznik w kolorze czarnym), wi\u0119c upewnij si\u0119, \u017Ce kszta\u0142t statecznika jest wype\u0142niony ciemnym kolorem, a t\u0142o jest bia\u0142e lub jasne. Podstawa statecznika musi przylega\u0107 do dolnej kraw\u0119dzi obrazu.
PresetModel.lbl.select = Wybierz ustawienia:
PresetModel.lbl.database = Z bazy danych...
PresetModel.lbl.custompreset = Niestandardowe
PresetModel.lbl.partsLib = Biblioteka cz??ci
! Component Preset Chooser Dialog

View File

@ -715,8 +715,8 @@ PreferencesDialog.languages.default = Padr\u00e3o do sistema
PreferencesDialog.lbl.language = Idioma da interface:
PreferencesDialog.lbl.languageEffect = A linguagem vai mudar na pr\u00f3xima vez que voc\u00ea iniciar o OpenRocket.
PresetModel.lbl.database = \u00c0 partir do banco de dados...
PresetModel.lbl.select = Selecione ajustes pr\u00e9-definidos
PresetModel.lbl.custompreset = Personalizado
PresetModel.lbl.partsLib = Biblioteca de pe\u00e7as
PrintDialog.but.previewAndPrint = Visualiza\u00e7\u00e3o e impress\u00e3o
PrintDialog.checkbox.showByStage = Mostrar por est\u00e1gio
@ -1386,14 +1386,13 @@ FileHelper.IMAGES = Arquivos de imagem
# General file type names
FileHelper.PDF_FILTER = Arquivos PDF (*.pdf)
main.menu.analyze = Analisar
main.menu.analyze.componentAnalysis = An\u00e1lise dos componentes
main.menu.analyze.componentAnalysis.desc = Analisar os componentes dos foguetes separadamente
main.menu.analyze.customExpressions = Express\u00f5es personalizadas
main.menu.analyze.customExpressions.desc = Definir novos tipos de dados de voo por escrito personalizados express\u00f5es matem\u00e1ticas
main.menu.analyze.desc = An\u00e1lise do foguete
main.menu.analyze.optimization = Otimiza\u00e7\u00e3o do foguete
main.menu.analyze.optimization.desc = Otimiza\u00e7\u00e3o do projeto geral do foguete
main.menu.tools = Analisar
main.menu.tools.componentAnalysis = An\u00e1lise dos componentes
main.menu.tools.componentAnalysis.desc = Analisar os componentes dos foguetes separadamente
main.menu.tools.customExpressions = Express\u00f5es personalizadas
main.menu.tools.customExpressions.desc = Definir novos tipos de dados de voo por escrito personalizados express\u00f5es matem\u00e1ticas
main.menu.tools.optimization = Otimiza\u00e7\u00e3o do foguete
main.menu.tools.optimization.desc = Otimiza\u00e7\u00e3o do projeto geral do foguete
main.menu.debug = Depura\u00e7\u00e3o
main.menu.debug.createtestrocket = Criar foguete de teste
main.menu.debug.whatisthismenu = O que \u00e9 esse menu?

View File

@ -293,8 +293,10 @@ pref.dlg.lbl.launchWarning.ttip = \u0412\u044B \u043D\u0435 \u043F\u0435\u0440\u
pref.dlg.lbl.Positiontoinsert = \u041C\u0435\u0441\u0442\u043E \u0434\u043B\u044F \u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F \u043D\u043E\u0432\u044B\u0445 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432:
pref.dlg.lbl.PositiontoinsertStages = \u041C\u0435\u0441\u0442\u043E \u0434\u043B\u044F \u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F \u043D\u043E\u0432\u044B\u0445 \u0441\u0442\u0443\u043F\u0435\u043D\u0435\u0439:
pref.dlg.lbl.Confirmdeletion = \u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0440\u0430\u0441\u0447\u0435\u0442\u0430:
pref.dlg.checkbox.Runsimulations = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u044B \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u0432\u043A\u043B\u0430\u0434\u043A\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043E\u0432.
pref.dlg.checkbox.Runsimulations = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u044B \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u0432\u043A\u043B\u0430\u0434\u043A\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043E\u0432
pref.dlg.checkbox.Updateestimates = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u043F\u0440\u0435\u0434\u043F\u043E\u043B\u0430\u0433\u0430\u0435\u043C\u044B\u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043F\u043E\u043B\u0435\u0442\u0430 \u0432 \u043E\u043A\u043D\u0435 \u043F\u0440\u043E\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F
pref.dlg.checkbox.Markers = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043C\u0430\u0440\u043A\u0435\u0440\u044B \u043E\u043F\u043E\u0440/\u0440\u0430\u0437\u0433\u043E\u043D\u043D\u044B\u0445 \u0431\u043B\u043E\u043A\u043E\u0432 \u0442\u043E\u043B\u044C\u043A\u043E \u0435\u0441\u043B\u0438 \u043E\u043D\u0438 \u0432\u044B\u0431\u0440\u0430\u043D\u044B
pref.dlg.checkbox.Markers.ttip = <html>\u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u043C\u0430\u0440\u043A\u0435\u0440\u044B \u043E\u043F\u043E\u0440/\u0440\u0430\u0437\u0433\u043E\u043D\u043D\u044B\u0445 \u0431\u043B\u043E\u043A\u043E\u0432 \u0431\u0443\u0434\u0443\u0442 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C\u0441\u044F, \u0442\u043E\u043B\u044C\u043A\u043E \u0435\u0441\u043B\u0438 \u043E\u043D\u0438 \u0432\u044B\u0431\u0440\u0430\u043D\u044B.<br>\u0412 \u043F\u0440\u043E\u0442\u0438\u0432\u043D\u043E\u043C \u0441\u043B\u0443\u0447\u0430\u0435 \u043C\u0430\u0440\u043A\u0435\u0440\u044B \u0431\u0443\u0434\u0443\u0442 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C\u0441\u044F \u0432\u0441\u0435\u0433\u0434\u0430.</html>
pref.dlg.checkbox.AlwaysOpenLeftmost = \u0412\u0441\u0435\u0433\u0434\u0430 \u0432\u044B\u0431\u0438\u0440\u0430\u0442\u044C \u043F\u0435\u0440\u0432\u0443\u044E \u0432\u043A\u043B\u0430\u0434\u043A\u0443 \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u043E\u043A\u043D\u0430 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430
pref.dlg.checkbox.AlwaysOpenLeftmost.ttip = <html>\u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432\u043E\u0435 \u043E\u043A\u043D\u043E \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0442\u044C\u0441\u044F \u0441 \u043F\u0435\u0440\u0432\u043E\u0439 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0439 \u0432\u043A\u043B\u0430\u0434\u043A\u043E\u0439.<br>\u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C\u0441\u044F \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0430\u044F \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u0430\u044F \u0432\u043A\u043B\u0430\u0434\u043A\u0430.</html>
pref.dlg.lbl.User-definedthrust = \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u043F\u0440\u043E\u0444\u0438\u043B\u0438 \u0442\u044F\u0433\u0438:
@ -716,7 +718,7 @@ compaddbuttons.Launchlug = \u041D\u0430\u043F\u0440\u0430\u0432\u043B\u044F\u044
compaddbuttons.RailButton = \u0417\u0430\u0446\u0435\u043F\n\u043D\u0430\u043F\u0440\u0430\u0432\u043B\u044F\u044E\u0449\u0435\u0439
compaddbuttons.InnerComponent = \u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0438\u0435 \u0434\u0435\u0442\u0430\u043B\u0438
compaddbuttons.Innertube = \u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F\n\u0442\u0440\u0443\u0431\u0430
compaddbuttons.Coupler = \u041C\u0443\u0444\u0442\u0430
compaddbuttons.Coupler = \u0422\u0440\u0443\u0431\u0447\u0430\u0442\u0430\u044F\n\u043C\u0443\u0444\u0442\u0430
compaddbuttons.Centeringring = \u0426\u0435\u043D\u0442\u0440\u0438\u0440\u0443\u044E\u0449\u0435\u0435\n\u043A\u043E\u043B\u044C\u0446\u043E
compaddbuttons.Bulkhead = \u041F\u0435\u0440\u0435\u0431\u043E\u0440\u043A\u0430
compaddbuttons.Engineblock = \u0423\u043F\u043E\u0440\n\u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u044F
@ -898,6 +900,7 @@ RocketCompCfg.tab.Figstyleopt = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440
RocketCompCfg.tab.Comment = \u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435
RocketCompCfg.tab.Comment.ttip = \u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435 \u043A \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0443
RocketCompCfg.tab.Appearance = \u0412\u043D\u0435\u0448\u043D\u0438\u0439 \u0432\u0438\u0434
RocketCompCfg.tab.Appearance.ttip = \u0412\u043D\u0435\u0448\u043D\u0438\u0439 \u0432\u0438\u0434 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430
RocketCompCfg.lbl.Mass = \u041C\u0430\u0441\u0441\u0430:
RocketCompCfg.lbl.Componentmass = \u041C\u0430\u0441\u0441\u0430 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430:
RocketCompCfg.lbl.overriddento = (\u043F\u0435\u0440\u0435\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043E \u043D\u0430
@ -1050,7 +1053,10 @@ LaunchLugCfg.tab.Generalprop = \u041E\u0441\u043D\u043E\u0432\u043D\u044B\u0435
! RailButtonConfig
RailBtnCfg.lbl.OuterDiam = \u0412\u043D\u0435\u0448\u043D\u0438\u0439 \u0434\u0438\u0430\u043C\u0435\u0442\u0440:
RailBtnCfg.lbl.TotalHeight = \u041E\u0431\u0449\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430
RailBtnCfg.lbl.InnerDiam = \u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0438\u0439 \u0434\u0438\u0430\u043C\u0435\u0442\u0440:
RailBtnCfg.lbl.TotalHeight = \u041E\u0431\u0449\u0430\u044F \u0432\u044B\u0441\u043E\u0442\u0430:
RailBtnCfg.lbl.BaseHeight = \u0412\u044B\u0441\u043E\u0442\u0430 \u043E\u0441\u043D\u043E\u0432\u0430\u043D\u0438\u044F:
RailBtnCfg.lbl.FlangeHeight = \u0412\u044B\u0441\u043E\u0442\u0430 \u0448\u043B\u044F\u043F\u043A\u0438::
RailBtnCfg.lbl.Angle = \u0423\u0433\u043E\u043B:
RailBtnCfg.lbl.PosRelativeTo = \u041F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0435\u043B\u044C\u043D\u043E:
RailBtnCfg.lbl.Plus = \u043F\u043B\u044E\u0441
@ -1373,14 +1379,13 @@ main.menu.edit.editpreset = \u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u0
main.menu.edit.preferences = \u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438
main.menu.edit.preferences.desc = \u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F
main.menu.analyze = \u0410\u043D\u0430\u043B\u0438\u0437
main.menu.analyze.desc = \u0410\u043D\u0430\u043B\u0438\u0437 \u0440\u0430\u043A\u0435\u0442\u044B
main.menu.analyze.componentAnalysis = \u0410\u043D\u0430\u043B\u0438\u0437 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432
main.menu.analyze.componentAnalysis.desc = \u0410\u043D\u0430\u043B\u0438\u0437 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432 \u0440\u0430\u043A\u0435\u0442\u044B \u043F\u043E \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u0438
main.menu.analyze.optimization = \u041E\u043F\u0442\u0438\u043C\u0438\u0437\u0430\u0446\u0438\u044F \u0440\u0430\u043A\u0435\u0442\u044B
main.menu.analyze.optimization.desc = \u041E\u0431\u0449\u0430\u044F \u043E\u043F\u0442\u0438\u043C\u0438\u0437\u0430\u0446\u0438\u044F \u043F\u0440\u043E\u0435\u043A\u0442\u0430 \u0440\u0430\u043A\u0435\u0442\u044B
main.menu.analyze.customExpressions = \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u044F
main.menu.analyze.customExpressions.desc = \u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u043D\u043E\u0432\u044B\u0445 \u0442\u0438\u043F\u043E\u0432 \u0434\u0430\u043D\u043D\u044B\u0445 \u043F\u043E\u043B\u0435\u0442\u0430 \u043D\u0430\u043F\u0438\u0441\u0430\u043D\u0438\u0435\u043C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445 \u043C\u0430\u0442\u0435\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0439
main.menu.tools = \u0410\u043D\u0430\u043B\u0438\u0437
main.menu.tools.componentAnalysis = \u0410\u043D\u0430\u043B\u0438\u0437 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432
main.menu.tools.componentAnalysis.desc = \u0410\u043D\u0430\u043B\u0438\u0437 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432 \u0440\u0430\u043A\u0435\u0442\u044B \u043F\u043E \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u0438
main.menu.tools.optimization = \u041E\u043F\u0442\u0438\u043C\u0438\u0437\u0430\u0446\u0438\u044F \u0440\u0430\u043A\u0435\u0442\u044B
main.menu.tools.optimization.desc = \u041E\u0431\u0449\u0430\u044F \u043E\u043F\u0442\u0438\u043C\u0438\u0437\u0430\u0446\u0438\u044F \u043F\u0440\u043E\u0435\u043A\u0442\u0430 \u0440\u0430\u043A\u0435\u0442\u044B
main.menu.tools.customExpressions = \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u044F
main.menu.tools.customExpressions.desc = \u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435 \u043D\u043E\u0432\u044B\u0445 \u0442\u0438\u043F\u043E\u0432 \u0434\u0430\u043D\u043D\u044B\u0445 \u043F\u043E\u043B\u0435\u0442\u0430 \u043D\u0430\u043F\u0438\u0441\u0430\u043D\u0438\u0435\u043C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445 \u043C\u0430\u0442\u0435\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0439
main.menu.help = \u0421\u043F\u0440\u0430\u0432\u043A\u0430
main.menu.help.desc = \u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E\u0431 OpenRocket
@ -2075,8 +2080,10 @@ CustomFinImport.error.badimage = \u041D\u0435\u0432\u043E\u0437\u043C\u043E\u043
CustomFinImport.description = \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044F \u0432 \u0447\u0435\u0440\u043D\u043E-\u0431\u0435\u043B\u043E\u0435 (\u0433\u0434\u0435 \u0447\u0435\u0440\u043D\u044B\u0439 - \u0446\u0432\u0435\u0442 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430), \u0442\u0430\u043A \u0447\u0442\u043E \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u0447\u0435\u0440\u043D\u044B\u0439 \u0446\u0432\u0435\u0442 \u0434\u043B\u044F \u0440\u0438\u0441\u0443\u043D\u043A\u0430 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430 \u0438 \u0431\u0435\u043B\u044B\u0439 \u0438\u043B\u0438 \u0441\u0432\u0435\u0442\u043B\u044B\u0439 \u0446\u0432\u0435\u0442 \u0434\u043B\u044F \u0444\u043E\u043D\u0430. \u041E\u0441\u043D\u043E\u0432\u0430\u043D\u0438\u0435 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430 \u0434\u043E\u043B\u0436\u043D\u043E \u043D\u0430\u0447\u0438\u043D\u0430\u0442\u044C\u0441\u044F \u0441\u043D\u0438\u0437\u0443 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F.
PresetModel.lbl.select = \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443
PresetModel.lbl.database = \u0418\u0437 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445...
PresetModel.combo.ttip = <html>\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443 \u0438\u0437 \u0441\u043F\u0438\u0441\u043A\u0430 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u044B\u0445 (\u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0445 \u0432 \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432\u043E\u043C \u043E\u043A\u043D\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043E\u043A \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432)<br>\u0438\u043B\u0438 \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0439", \u0435\u0441\u043B\u0438 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0430 \u043D\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F.</html>
PresetModel.lbl.custompreset = \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u0438\u0439
PresetModel.lbl.partsLib = \u0411\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430 \u0434\u0435\u0442\u0430\u043B\u0435\u0439
PresetModel.lbl.partsLib.ttip = \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443 \u0434\u043B\u044F \u044D\u0442\u043E\u0433\u043E \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 \u0440\u0430\u043A\u0435\u0442\u044B \u0438\u0437 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u0434\u0435\u0442\u0430\u043B\u0435\u0439.
DecalModel.lbl.select = <\u043D\u0435\u0442>
DecalModel.lbl.choose = \u0418\u0437 \u0444\u0430\u0439\u043B\u0430...
@ -2098,7 +2105,7 @@ ComponentPresetChooserDialog.menu.sortDesc = \u041F\u043E \u0443\u0431\u044B\u04
ComponentPresetChooserDialog.menu.units = \u0415\u0434\u0438\u043D\u0438\u0446\u044B \u0438\u0437\u043C\u0435\u0440\u0435\u043D\u0438\u044F
ComponentPresetChooserDialog.checkbox.showAllCompatible = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432\u0441\u0435 \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u044B\u0435
ComponentPresetChooserDialog.checkbox.showLegacyCheckBox = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0431\u0430\u0437\u0443 \u0434\u0430\u043D\u043D\u044B\u0445 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0445
ComponentPresetChooserDialog.lbl.favorites = \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u043B\u044F \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0432 \u0432\u044B\u043F\u0430\u0434\u0430\u044E\u0449\u0435\u0435 \u043C\u0435\u043D\u044E
ComponentPresetChooserDialog.lbl.favorites = \u0423\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0435 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A, \u0447\u0442\u043E\u0431\u044B \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443 \u0432 \u0440\u0430\u0441\u043A\u0440\u044B\u0432\u0430\u044E\u0449\u0435\u0435\u0441\u044F \u043C\u0435\u043D\u044E \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043E\u043A \u0432 \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432\u043E\u043C \u043E\u043A\u043D\u0435 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430.
table.column.Favorite = \u0418\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0435
table.column.Legacy = \u0423\u0441\u0442\u0430\u0440\u0435\u043B\u043E
table.column.Manufacturer = \u041F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C
@ -2115,7 +2122,7 @@ table.column.AftShoulderDiameter = \u0414\u0438\u0430\u043C\u0435\u0442\u0440 \u
table.column.ForeShoulderLength = \u0414\u043B\u0438\u043D\u0430 \u043F\u0435\u0440\u0435\u0434\u043D\u0435\u0439 \u043C\u0443\u0444\u0442\u044B
table.column.ForeShoulderDiameter = \u0414\u0438\u0430\u043C\u0435\u0442\u0440 \u043F\u0435\u0440\u0435\u0434\u043D\u0435\u0439 \u043C\u0443\u0444\u0442\u044B
table.column.ForeOuterDiameter = \u0412\u043D\u0435\u0448\u043D\u0438\u0439 \u0434\u0438\u0430\u043C\u0435\u0442\u0440 \u043F\u0435\u0440\u0435\u0434\u043D\u0435\u0439 \u043C\u0443\u0444\u0442\u044B
table.column.StandoffHeight = \u0412\u044B\u0441\u043E\u0442\u0430 \u0437\u0430\u0437\u043E\u0440\u0430
table.column.BaseHeight = \u0412\u044B\u0441\u043E\u0442\u0430 \u0437\u0430\u0437\u043E\u0440\u0430
table.column.FlangeHeight = \u0412\u044B\u0441\u043E\u0442\u0430 \u0444\u043B\u0430\u043D\u0446\u0430
table.column.Shape = \u0424\u043E\u0440\u043C\u0430
table.column.Material = \u041C\u0430\u0442\u0435\u0440\u0438\u0430\u043B

View File

@ -1175,14 +1175,13 @@ main.menu.edit.editpreset= Edit Component Preset File
main.menu.edit.preferences = Preferences
main.menu.edit.preferences.desc = Setup the application preferences
main.menu.analyze = Tools
main.menu.analyze.desc = Rocket analysis
main.menu.analyze.componentAnalysis = Component analysis
main.menu.analyze.componentAnalysis.desc = Analyze the rocket components separately
main.menu.analyze.optimization = Rocket optimization
main.menu.analyze.optimization.desc = General rocket design optimization
main.menu.analyze.customExpressions = Custom expressions
main.menu.analyze.customExpressions.desc = Define new flight data types by writing custom mathematical expressions
main.menu.tools = Tools
main.menu.tools.componentAnalysis = Component analysis
main.menu.tools.componentAnalysis.desc = Analyze the rocket components separately
main.menu.tools.optimization = Rocket optimization
main.menu.tools.optimization.desc = General rocket design optimization
main.menu.tools.customExpressions = Custom expressions
main.menu.tools.customExpressions.desc = Define new flight data types by writing custom mathematical expressions
main.menu.help = Help
main.menu.help.desc = Information about OpenRocket
@ -1812,8 +1811,8 @@ CustomFinImport.error.badimage = Could not deduce fin shape from image.
CustomFinImport.description = The image will be converted internally to black and white image (black for the fin), so make sure you use a solid dark color for the fin, and white or a light color for the background. The fin must be touching the bottom of the image, which is the base of the fin.
PresetModel.lbl.select = Select preset
PresetModel.lbl.database = From database...
PresetModel.lbl.custompreset = Custom
PresetModel.lbl.partsLib = Parts Library
DecalModel.lbl.select = <none>
DecalModel.lbl.choose = From file...

View File

@ -803,8 +803,8 @@ PreferencesDialog.languages.default = \u7CFB\u7EDF\u9ED8\u8BA4
PreferencesDialog.lbl.language = \u754C\u9762\u8BED\u8A00:
PreferencesDialog.lbl.languageEffect = \u8BED\u8A00\u8BBE\u7F6E\u5C06\u5728OpenRocket\u91CD\u542F\u540E\u751F\u6548
PresetModel.lbl.database = \u4ECE\u6570\u636E\u5E93...
PresetModel.lbl.select = \u9009\u62E9\u9884\u8BBE
PresetModel.lbl.custompreset = \u5b9a\u5236
PresetModel.lbl.partsLib = \u96f6\u4ef6\u5e93
PrintDialog.but.previewAndPrint = \u9884\u89C8 & \u6253\u5370
PrintDialog.checkbox.showByStage = \u6309\u7EA7\u663E\u793A
@ -1509,14 +1509,13 @@ generalprefs.languages.default = \u7CFB\u7EDF\u9ED8\u8BA4
generalprefs.lbl.language = \u754C\u9762\u8BED\u8A00
generalprefs.lbl.languageEffect = \u65B0\u7684\u8BED\u8A00\u5C06\u5728\u4E0B\u6B21\u542F\u52A8OpenRocket\u65F6\u751F\u6548.
main.menu.analyze = \u5206\u6790
main.menu.analyze.componentAnalysis = \u7EC4\u4EF6\u5206\u6790
main.menu.analyze.componentAnalysis.desc = \u4EC5\u5206\u6790\u706B\u7BAD\u90E8\u4EF6
main.menu.analyze.customExpressions = \u81EA\u5B9A\u4E49\u8868\u8FBE\u5F0F
main.menu.analyze.customExpressions.desc = \u901A\u8FC7\u81EA\u5B9A\u4E49\u7684\u6570\u5B66\u8868\u8FBE\u5F0F\u6765\u5B9A\u4E49\u65B0\u7684\u98DE\u884C\u6570\u636E\u7C7B\u578B
main.menu.analyze.desc = \u706B\u7BAD\u5206\u6790
main.menu.analyze.optimization = \u706B\u7BAD\u4F18\u5316
main.menu.analyze.optimization.desc = \u5E38\u89C4\u706B\u7BAD\u8BBE\u8BA1\u4F18\u5316
main.menu.tools = \u5206\u6790
main.menu.tools.componentAnalysis = \u7EC4\u4EF6\u5206\u6790
main.menu.tools.componentAnalysis.desc = \u4EC5\u5206\u6790\u706B\u7BAD\u90E8\u4EF6
main.menu.tools.customExpressions = \u81EA\u5B9A\u4E49\u8868\u8FBE\u5F0F
main.menu.tools.customExpressions.desc = \u901A\u8FC7\u81EA\u5B9A\u4E49\u7684\u6570\u5B66\u8868\u8FBE\u5F0F\u6765\u5B9A\u4E49\u65B0\u7684\u98DE\u884C\u6570\u636E\u7C7B\u578B
main.menu.tools.optimization = \u706B\u7BAD\u4F18\u5316
main.menu.tools.optimization.desc = \u5E38\u89C4\u706B\u7BAD\u8BBE\u8BA1\u4F18\u5316
main.menu.debug = \u8C03\u8BD5
main.menu.debug.createtestrocket = \u5EFA\u7ACB\u6D4B\u8BD5\u706B\u7BAD
main.menu.debug.whatisthismenu = \u8FD9\u662F\u4EC0\u4E48\u83DC\u5355?

Binary file not shown.

Before

Width:  |  Height:  |  Size: 705 B

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 671 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 751 B

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 667 B

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 549 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 B

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 652 B

After

Width:  |  Height:  |  Size: 652 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 1020 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1008 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 835 B

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 670 B

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 550 B

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 948 B

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -10,6 +10,7 @@ import org.slf4j.LoggerFactory;
import net.sf.openrocket.aerodynamics.barrowman.FinSetCalc;
import net.sf.openrocket.aerodynamics.barrowman.RocketComponentCalc;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.ExternalComponent;
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
@ -370,9 +371,10 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
final RocketComponent c = entry.getKey();
if (!c.isAerodynamic())
if (!c.isAerodynamic()) {
continue;
}
// Handle Overriden CD for Whole Rocket
if(c.isCDOverridden()) {
continue;
@ -406,32 +408,30 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
componentCf = Math.max(Cf, roughnessLimited[finish.ordinal()]);
}
// iterate across component instances
final ArrayList<InstanceContext> contextList = entry.getValue();
for(InstanceContext context: contextList ) {
double componentFrictionCD = calcMap.get(c).calculateFrictionCD(conditions, componentCf, warningSet);
if (c instanceof SymmetricComponent) {
SymmetricComponent s = (SymmetricComponent) c;
bodyFrictionCD += componentFrictionCD;
double componentFrictionCD = calcMap.get(c).calculateFrictionCD(conditions, componentCf, warningSet);
final double componentMinX = context.getLocation().x;
minX = Math.min(minX, componentMinX);
int instanceCount = entry.getValue().size();
if (c instanceof SymmetricComponent) {
SymmetricComponent s = (SymmetricComponent) c;
final double componentMaxX = componentMinX + c.getLength();
maxX = Math.max(maxX, componentMaxX);
bodyFrictionCD += instanceCount * componentFrictionCD;
final double componentMinX = c.getAxialOffset(AxialMethod.ABSOLUTE);
minX = Math.min(minX, componentMinX);
final double componentMaxR = Math.max(s.getForeRadius(), s.getAftRadius());
maxR = Math.max(maxR, componentMaxR);
} else {
otherFrictionCD += componentFrictionCD;
}
final double componentMaxX = componentMinX + c.getLength();
maxX = Math.max(maxX, componentMaxX);
if (map != null) {
map.get(c).setFrictionCD(componentFrictionCD);
}
final double componentMaxR = Math.max(s.getForeRadius(), s.getAftRadius());
maxR = Math.max(maxR, componentMaxR);
} else {
otherFrictionCD += instanceCount * componentFrictionCD;
}
if (map != null) {
map.get(c).setFrictionCD(componentFrictionCD);
}
}
@ -447,7 +447,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
}
}
}
return otherFrictionCD + correction * bodyFrictionCD;
}
@ -590,57 +590,58 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
*/
private double calculatePressureCD(FlightConfiguration configuration, FlightConditions conditions,
Map<RocketComponent, AerodynamicForces> forceMap, WarningSet warningSet) {
double stagnation, base, total;
double total, stagnation, base;
if (calcMap == null)
buildCalcMap(configuration);
stagnation = calculateStagnationCD(conditions.getMach());
base = calculateBaseCD(conditions.getMach());
total = 0;
final InstanceMap imap = configuration.getActiveInstances();
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
final RocketComponent c = entry.getKey();
if (!c.isAerodynamic())
if (!c.isAerodynamic()) {
continue;
}
if(c.isCDOverridden()) {
continue;
}
int instanceCount = entry.getValue().size();
// iterate across component instances
final ArrayList<InstanceContext> contextList = entry.getValue();
for(InstanceContext context: contextList ) {
// Pressure drag
double cd = calcMap.get(c).calculatePressureCD(conditions, stagnation, base,
// Pressure drag of this component
double cd = calcMap.get(c).calculatePressureCD(conditions, stagnation, base,
warningSet);
total += cd;
if (forceMap != null) {
forceMap.get(c).setPressureCD(cd);
}
if (forceMap != null) {
forceMap.get(c).setPressureCD(cd);
}
total += cd * instanceCount;
// Stagnation drag caused by difference in radius between this component
// and previous component (increasing radii. Decreasing radii handled in
// base drag calculation
if (c instanceof SymmetricComponent) {
SymmetricComponent s = (SymmetricComponent) c;
if(c.isCDOverridden())
continue;
// Stagnation drag
if (c instanceof SymmetricComponent) {
SymmetricComponent s = (SymmetricComponent) c;
double radius = 0;
final SymmetricComponent prevComponent = s.getPreviousSymmetricComponent();
if (prevComponent != null && configuration.isComponentActive(prevComponent))
radius = prevComponent.getAftRadius();
double radius = 0;
final SymmetricComponent prevComponent = s.getPreviousSymmetricComponent();
if (prevComponent != null && configuration.isComponentActive(prevComponent))
radius = prevComponent.getAftRadius();
if (radius < s.getForeRadius()) {
double area = Math.PI * (pow2(s.getForeRadius()) - pow2(radius));
cd = stagnation * area / conditions.getRefArea();
total += cd;
if (radius < s.getForeRadius()) {
double area = Math.PI * (pow2(s.getForeRadius()) - pow2(radius));
cd = stagnation * area / conditions.getRefArea();
total += instanceCount * cd;
if (forceMap != null) {
forceMap.get(c).setPressureCD(forceMap.get(c).getPressureCD() + cd);
}
}
}
}
}
@ -673,47 +674,46 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
final RocketComponent c = entry.getKey();
if (!(c instanceof SymmetricComponent))
if (!(c instanceof SymmetricComponent)) {
continue;
}
SymmetricComponent s = (SymmetricComponent) c;
int instanceCount = entry.getValue().size();
// iterate across component instances
final ArrayList<InstanceContext> contextList = entry.getValue();
for(InstanceContext context: contextList ) {
if(c.isCDOverridden()) {
total += c.getOverrideCD();
continue;
}
if(c.isCDOverridden()) {
total += instanceCount * c.getOverrideCD();
continue;
}
// if aft radius of previous component is greater than my forward radius, set
// its aft CD
double radius = 0;
final SymmetricComponent prevComponent = s.getPreviousSymmetricComponent();
if (prevComponent != null && configuration.isComponentActive(prevComponent)) {
radius = prevComponent.getAftRadius();
// if aft radius of previous component is greater than my forward radius, set
// its aft CD
double radius = 0;
final SymmetricComponent prevComponent = s.getPreviousSymmetricComponent();
if (prevComponent != null && configuration.isComponentActive(prevComponent)) {
radius = prevComponent.getAftRadius();
}
if (radius > s.getForeRadius()) {
double area = Math.PI * (pow2(radius) - pow2(s.getForeRadius()));
double cd = base * area / conditions.getRefArea();
total += instanceCount * cd;
if ((map != null) && (prevComponent != null)) {
map.get(prevComponent).setBaseCD(cd);
}
}
if (radius > s.getForeRadius()) {
double area = Math.PI * (pow2(radius) - pow2(s.getForeRadius()));
double cd = base * area / conditions.getRefArea();
total += cd;
if ((map != null) && (prevComponent != null)) {
map.get(prevComponent).setBaseCD(cd);
}
}
// if I'm the last component, set my base CD
// note: the iterator *should* serve up the next component.... buuuut ....
// this code has is tested, and there's no compelling reason to change.
final SymmetricComponent n = s.getNextSymmetricComponent();
if ((n == null) || !configuration.isStageActive(n.getStageNumber())) {
double area = Math.PI * pow2(s.getAftRadius());
double cd = base * area / conditions.getRefArea();
total += cd;
if (map != null) {
map.get(s).setBaseCD(cd);
}
// if I'm the last component, set my base CD
// note: the iterator *should* serve up the next component.... buuuut ....
// this code has is tested, and there's no compelling reason to change.
final SymmetricComponent n = s.getNextSymmetricComponent();
if ((n == null) || !configuration.isStageActive(n.getStageNumber())) {
double area = Math.PI * pow2(s.getAftRadius());
double cd = base * area / conditions.getRefArea();
total += instanceCount * cd;
if (map != null) {
map.get(s).setBaseCD(cd);
}
}
}
@ -885,8 +885,9 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
calcMap = new HashMap<>();
for (RocketComponent comp: configuration.getAllComponents()) {
if (!comp.isAerodynamic())
if (!comp.isAerodynamic()) {
continue;
}
RocketComponentCalc calcObj = (RocketComponentCalc) Reflection.construct(BARROWMAN_PACKAGE, comp, BARROWMAN_SUFFIX, comp);

View File

@ -190,8 +190,15 @@ class DocumentConfig {
setters.put("RailButton:angleoffset", new AnglePositionSetter() );
setters.put("RailButton:height", new DoubleSetter(
Reflection.findMethod( RailButton.class, "setTotalHeight", double.class)));
setters.put("RailButton:baseheight", new DoubleSetter(
Reflection.findMethod( RailButton.class, "setBaseHeight", double.class)));
setters.put("RailButton:flangeheight", new DoubleSetter(
Reflection.findMethod( RailButton.class, "setFlangeHeight", double.class)));
setters.put("RailButton:outerdiameter", new DoubleSetter(
Reflection.findMethod( RailButton.class, "setOuterDiameter", double.class)));
setters.put("RailButton:innerdiameter", new DoubleSetter(
Reflection.findMethod( RailButton.class, "setInnerDiameter", double.class)));
// Transition
setters.put("Transition:shape", new EnumSetter<Transition.Shape>(

View File

@ -26,8 +26,10 @@ public class RailButtonSaver extends ExternalComponentSaver {
RailButton rb = (RailButton) c;
emitDouble( elements, "outerdiameter", rb.getOuterDiameter());
emitDouble( elements, "innerdiameter", rb.getInnerDiameter());
emitDouble( elements, "height", rb.getTotalHeight());
emitDouble( elements, "baseheight", rb.getBaseHeight());
emitDouble( elements, "flangeheight", rb.getFlangeHeight());
}

View File

@ -129,12 +129,16 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
ComponentPreset.MANUFACTURER,
ComponentPreset.PARTNO,
ComponentPreset.DESCRIPTION,
// these are optional / secondary parameters. Probably not necessary to include.
//ComponentPreset.BASE_HEIGHT,
//ComponentPreset.FLANGE_HEIGHT,
//ComponentPreset.INNER_DIAMETER,
ComponentPreset.BASE_HEIGHT,
ComponentPreset.FLANGE_HEIGHT,
//ComponentPreset.SCREW_HEIGHT, // Add this later when we implement screws in the rail button
ComponentPreset.HEIGHT,
ComponentPreset.INNER_DIAMETER,
ComponentPreset.OUTER_DIAMETER,
ComponentPreset.HEIGHT }),
ComponentPreset.MASS,
ComponentPreset.SCREW_MASS,
ComponentPreset.NUT_MASS,
ComponentPreset.CD }),
STREAMER(new TypedKey<?>[] {
ComponentPreset.LEGACY,
@ -160,7 +164,7 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
ComponentPreset.LINE_COUNT,
ComponentPreset.LINE_LENGTH,
ComponentPreset.LINE_MATERIAL,
ComponentPreset.PARACHUTE_CD,
ComponentPreset.CD,
ComponentPreset.PACKED_DIAMETER,
ComponentPreset.PACKED_LENGTH });
@ -206,6 +210,7 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
public final static TypedKey<Double> AFT_SHOULDER_LENGTH = new TypedKey<Double>("AftShoulderLength", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> AFT_SHOULDER_DIAMETER = new TypedKey<Double>("AftShoulderDiameter", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> AFT_OUTER_DIAMETER = new TypedKey<Double>("AftOuterDiameter", Double.class, UnitGroup.UNITS_LENGTH);
public static final TypedKey<Double> CD = new TypedKey<Double>("DragCoefficient", Double.class, UnitGroup.UNITS_COEFFICIENT);
public final static TypedKey<Shape> SHAPE = new TypedKey<Shape>("Shape", Shape.class);
public final static TypedKey<Material> MATERIAL = new TypedKey<Material>("Material", Material.class);
public final static TypedKey<Finish> FINISH = new TypedKey<Finish>("Finish", Finish.class);
@ -214,8 +219,13 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
public final static TypedKey<Double> MASS = new TypedKey<Double>("Mass", Double.class, UnitGroup.UNITS_MASS);
public final static TypedKey<Double> DIAMETER = new TypedKey<Double>("Diameter", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<byte[]> IMAGE = new TypedKey<byte[]>("Image", byte[].class);
public final static TypedKey<Double> STANDOFF_HEIGHT = new TypedKey<Double>("StandoffHeight", Double.class, UnitGroup.UNITS_LENGTH);
// RAIL BUTTON SPECIFIC
public final static TypedKey<Double> BASE_HEIGHT = new TypedKey<Double>("BaseHeight", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> FLANGE_HEIGHT = new TypedKey<Double>("FlangeHeight", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> SCREW_HEIGHT = new TypedKey<Double>("ScrewHeight", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> SCREW_MASS = new TypedKey<Double>("ScrewMass", Double.class, UnitGroup.UNITS_MASS);
public final static TypedKey<Double> NUT_MASS = new TypedKey<Double>("NutMass", Double.class, UnitGroup.UNITS_MASS);
// PARACHUTE SPECIFIC
// Parachute Manufacturer declaration see: MANUFACTURER
@ -225,7 +235,7 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
// Parachute diameter declaration see: DIAMETER
public final static TypedKey<Double> SPILL_DIA = new TypedKey<Double>("SpillDia", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> SURFACE_AREA = new TypedKey<Double>("SurfaceArea", Double.class, UnitGroup.UNITS_LENGTH);
public static final TypedKey<Double> PARACHUTE_CD = new TypedKey<Double>("DragCoefficient", Double.class, UnitGroup.UNITS_COEFFICIENT);
// Parachute canopy material declaration see: MATERIAL
public final static TypedKey<Integer> SIDES = new TypedKey<Integer>("Sides", Integer.class);
public final static TypedKey<Integer> LINE_COUNT = new TypedKey<Integer>("LineCount", Integer.class);
@ -251,8 +261,9 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
AFT_SHOULDER_LENGTH,
FORE_SHOULDER_DIAMETER,
FORE_SHOULDER_LENGTH,
STANDOFF_HEIGHT,
BASE_HEIGHT,
FLANGE_HEIGHT,
SCREW_HEIGHT,
SHAPE,
THICKNESS,
FILLED,
@ -262,6 +273,8 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
LINE_LENGTH,
LINE_MATERIAL,
MASS,
SCREW_MASS,
NUT_MASS,
FINISH,
MATERIAL
));
@ -411,6 +424,9 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
os.writeDouble(d);
} else if (key.getType() == String.class) {
String s = (String) value;
if (s == null) {
s = "";
}
os.writeBytes(s);
} else if (key.getType() == Manufacturer.class) {
String s = ((Manufacturer) value).getSimpleName();

View File

@ -113,13 +113,13 @@ public abstract class ComponentPresetFactory {
}
private static void makeRailButton(InvalidComponentPresetException exceptions, ComponentPreset preset) throws InvalidComponentPresetException {
private static void makeRailButton(InvalidComponentPresetException exceptions, ComponentPreset preset) {
checkRequiredFields(exceptions, preset, HEIGHT);
checkRequiredFields(exceptions, preset, OUTER_DIAMETER);
checkRequiredFields(exceptions, preset, INNER_DIAMETER);
checkRequiredFields(exceptions, preset, FLANGE_HEIGHT);
checkRequiredFields(exceptions, preset, STANDOFF_HEIGHT);
checkRequiredFields(exceptions, preset, BASE_HEIGHT);
if (preset.has(MASS)) {
double mass = preset.get(MASS);
@ -271,7 +271,6 @@ public abstract class ComponentPresetFactory {
if (hasOd) {
outerRadius = preset.get(OUTER_DIAMETER) / 2.0;
thickness = 0;
if (hasId) {
innerRadius = preset.get(INNER_DIAMETER) / 2.0;
thickness = outerRadius - innerRadius;

View File

@ -13,7 +13,7 @@ public class RailButtonLoader extends BaseComponentLoader {
fileColumns.add(new DoubleUnitColumnParser("OD","Units",ComponentPreset.OUTER_DIAMETER));
fileColumns.add(new DoubleUnitColumnParser("Height","Units",ComponentPreset.HEIGHT));
fileColumns.add(new DoubleUnitColumnParser("Flange Height", "Units", ComponentPreset.FLANGE_HEIGHT));
fileColumns.add(new DoubleUnitColumnParser("Standoff Height", "Units", ComponentPreset.STANDOFF_HEIGHT));
fileColumns.add(new DoubleUnitColumnParser("Standoff Height", "Units", ComponentPreset.BASE_HEIGHT));
}

View File

@ -34,9 +34,7 @@ public class OpenRocketComponentLoader implements Loader<ComponentPreset> {
presets = (new OpenRocketComponentSaver().unmarshalFromOpenRocketComponent( new InputStreamReader (stream))).asComponentPresets();
log.debug("ComponentPreset file " + filename + " contained " + presets.size() + " presets");
return presets;
} catch (JAXBException e) {
throw new BugException("Unable to parse file: "+ filename, e);
} catch (InvalidComponentPresetException e) {
} catch (JAXBException | InvalidComponentPresetException e) {
throw new BugException("Unable to parse file: "+ filename, e);
}

View File

@ -146,8 +146,8 @@ public class ParachuteDTO extends BaseComponentDTO {
if ( preset.has(ComponentPreset.PACKED_LENGTH)) {
setPackedLength(preset.get(ComponentPreset.PACKED_LENGTH));
}
if ( preset.has(ComponentPreset.PARACHUTE_CD)) {
setDragCoefficient(preset.get(ComponentPreset.PARACHUTE_CD));
if ( preset.has(ComponentPreset.CD)) {
setDragCoefficient(preset.get(ComponentPreset.CD));
}
if ( preset.has(ComponentPreset.LINE_MATERIAL)) {
setLineMaterial(new AnnotatedMaterialDTO(preset.get(ComponentPreset.LINE_MATERIAL)));
@ -174,7 +174,7 @@ public class ParachuteDTO extends BaseComponentDTO {
props.put(ComponentPreset.PACKED_LENGTH, this.getPackedLength());
}
if ( this.dragCoefficient != null ) {
props.put(ComponentPreset.PARACHUTE_CD, this.getDragCoefficient());
props.put(ComponentPreset.CD, this.getDragCoefficient());
}
props.put(ComponentPreset.LINE_COUNT, this.getLineCount());
if ( this.lineLength != null ) {

View File

@ -19,16 +19,22 @@ import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
public class RailButtonDTO extends BaseComponentDTO {
@XmlElement(name = "InsideDiameter")
private AnnotatedLengthDTO insideDiameter;
@XmlElement(name = "OutsideDiameter")
private AnnotatedLengthDTO outsideDiameter;
@XmlElement(name = "InnerDiameter")
private AnnotatedLengthDTO innerDiameter;
@XmlElement(name = "OuterDiameter")
private AnnotatedLengthDTO outerDiameter;
@XmlElement(name = "Height")
private AnnotatedLengthDTO height;
@XmlElement(name = "StandoffHeight")
private AnnotatedLengthDTO standoffHeight;
@XmlElement(name = "BaseHeight")
private AnnotatedLengthDTO baseHeight;
@XmlElement(name = "FlangeHeight")
private AnnotatedLengthDTO flangeHeight;
@XmlElement(name = "ScrewHeight")
private AnnotatedLengthDTO screwHeight;
@XmlElement(name = "ScrewMass")
private AnnotatedMassDTO screwMass;
@XmlElement(name = "NutMass")
private AnnotatedMassDTO nutMass;
/**
* Default constructor.
@ -48,32 +54,35 @@ public class RailButtonDTO extends BaseComponentDTO {
setInsideDiameter(preset.get(ComponentPreset.INNER_DIAMETER));
setOutsideDiameter(preset.get(ComponentPreset.OUTER_DIAMETER));
setHeight(preset.get(ComponentPreset.HEIGHT));
setStandoffHeight(preset.get(ComponentPreset.STANDOFF_HEIGHT));
setBaseHeight(preset.get(ComponentPreset.BASE_HEIGHT));
setFlangeHeight(preset.get(ComponentPreset.FLANGE_HEIGHT));
setScrewHeight(preset.get(ComponentPreset.SCREW_HEIGHT));
setScrewMass(preset.get(ComponentPreset.SCREW_MASS));
setNutMass(preset.get(ComponentPreset.NUT_MASS));
}
public double getInsideDiameter() {
return insideDiameter.getValue();
public double getInnerDiameter() {
return innerDiameter.getValue();
}
public void setInsideDiameter( final AnnotatedLengthDTO theLength ) {
insideDiameter = theLength;
public void setInnerDiameter(final AnnotatedLengthDTO theLength ) {
innerDiameter = theLength;
}
public void setInsideDiameter(final double theId) {
insideDiameter = new AnnotatedLengthDTO(theId);
innerDiameter = new AnnotatedLengthDTO(theId);
}
public double getOutsideDiameter() {
return outsideDiameter.getValue();
public double getOuterDiameter() {
return outerDiameter.getValue();
}
public void setOutsideDiameter(final AnnotatedLengthDTO theOd) {
outsideDiameter = theOd;
public void setOuterDiameter(final AnnotatedLengthDTO theOd) {
outerDiameter = theOd;
}
public void setOutsideDiameter(final double theOd) {
outsideDiameter = new AnnotatedLengthDTO(theOd);
outerDiameter = new AnnotatedLengthDTO(theOd);
}
public double getHeight() {
@ -88,16 +97,12 @@ public class RailButtonDTO extends BaseComponentDTO {
height = new AnnotatedLengthDTO(theHeight);
}
public double getStandoffHeight() {
return standoffHeight.getValue();
public double getBaseHeight() {
return baseHeight.getValue();
}
public void setStandoffHeight(final AnnotatedLengthDTO theStandoffHeight) {
standoffHeight = theStandoffHeight;
}
public void setStandoffHeight(final double theStandoffHeight) {
standoffHeight = new AnnotatedLengthDTO(theStandoffHeight);
public void setBaseHeight(final double theBaseHeight) {
baseHeight = new AnnotatedLengthDTO(theBaseHeight);
}
public double getFlangeHeight() {
@ -112,6 +117,30 @@ public class RailButtonDTO extends BaseComponentDTO {
flangeHeight = new AnnotatedLengthDTO(theFlangeHeight);
}
public double getScrewHeight() {
return screwHeight.getValue();
}
public void setScrewHeight(final double screwHeight) {
this.screwHeight = new AnnotatedLengthDTO(screwHeight);
}
public double getScrewMass() {
return screwMass.getValue();
}
public void setScrewMass(double screwMass) {
this.screwMass = new AnnotatedMassDTO(screwMass);
}
public double getNutMass() {
return nutMass.getValue();
}
public void setNutMass(double nutMass) {
this.nutMass = new AnnotatedMassDTO(nutMass);
}
@Override
public ComponentPreset asComponentPreset(Boolean legacy, java.util.List<MaterialDTO> materials) throws InvalidComponentPresetException {
return asComponentPreset(legacy, ComponentPreset.Type.RAIL_BUTTON, materials);
@ -121,11 +150,14 @@ public class RailButtonDTO extends BaseComponentDTO {
TypedPropertyMap props = new TypedPropertyMap();
props.put(ComponentPreset.LEGACY, legacy);
addProps(props, materials);
props.put(ComponentPreset.INNER_DIAMETER, this.getInsideDiameter());
props.put(ComponentPreset.OUTER_DIAMETER, this.getOutsideDiameter());
props.put(ComponentPreset.INNER_DIAMETER, this.getInnerDiameter());
props.put(ComponentPreset.OUTER_DIAMETER, this.getOuterDiameter());
props.put(ComponentPreset.HEIGHT, this.getHeight());
props.put(ComponentPreset.STANDOFF_HEIGHT, this.getStandoffHeight());
props.put(ComponentPreset.BASE_HEIGHT, this.getBaseHeight());
props.put(ComponentPreset.FLANGE_HEIGHT, this.getFlangeHeight());
props.put(ComponentPreset.SCREW_HEIGHT, this.getScrewHeight());
props.put(ComponentPreset.SCREW_MASS, this.getScrewMass());
props.put(ComponentPreset.NUT_MASS, this.getNutMass());
props.put(ComponentPreset.TYPE, type);
return ComponentPresetFactory.create(props);

View File

@ -144,7 +144,9 @@ public abstract class ExternalComponent extends RocketComponent {
protected void loadFromPreset(ComponentPreset preset) {
super.loadFromPreset(preset);
// Surface finish is left unchanged
if (preset.has(ComponentPreset.FINISH)) {
setFinish(preset.get(ComponentPreset.FINISH));
}
if (preset.has(ComponentPreset.MATERIAL)) {
Material mat = preset.get(ComponentPreset.MATERIAL);

View File

@ -227,8 +227,8 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
if (MathUtil.equals(clampedCant, this.cantRadians))
return;
this.cantRadians = clampedCant;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
}
public Transformation getCantRotation() {

View File

@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -62,7 +63,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
/* Cached data */
final protected Map<Integer, StageFlags> stages = new HashMap<Integer, StageFlags>(); // Map of stage number to StageFlags of the corresponding stage
final protected Map<MotorConfigurationId, MotorConfiguration> motors = new HashMap<MotorConfigurationId, MotorConfiguration>();
final private Collection<MotorConfiguration> activeMotors = new ArrayList<MotorConfiguration>();
final private Collection<MotorConfiguration> activeMotors = new ConcurrentLinkedQueue<MotorConfiguration>();
final private InstanceMap activeInstances = new InstanceMap();
private int boundsModID = -1;
@ -225,8 +226,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
for (AxialStage stage : rocket.getStage(stageNumber).getSubStages()) {
stages.get(stage.getStageNumber()).active = flags.active;
}
updateMotors();
updateActiveInstances();
fireChangeEvent();
return;
}
@ -377,7 +377,11 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
for (StageFlags flags : this.stages.values()) {
if (flags.active) {
activeStages.add( rocket.getStage( flags.stageNumber) );
AxialStage stage = rocket.getStage(flags.stageNumber);
if (stage == null) {
continue;
}
activeStages.add(stage);
}
}

View File

@ -1,9 +1,9 @@
package net.sf.openrocket.rocketcomponent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import net.sf.openrocket.util.Transformation;
@ -13,7 +13,7 @@ import net.sf.openrocket.util.Transformation;
* @author teyrana (aka Daniel Williams) <equipoise@gmail.com>
*
*/
public class InstanceMap extends HashMap<RocketComponent, ArrayList<InstanceContext>> {
public class InstanceMap extends ConcurrentHashMap<RocketComponent, ArrayList<InstanceContext>> {
// =========== Public Functions ========================

View File

@ -2,10 +2,7 @@ package net.sf.openrocket.rocketcomponent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EventObject;
import net.sf.openrocket.appearance.Appearance;
import net.sf.openrocket.appearance.Decal;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.ComponentPreset.Type;
@ -14,7 +11,6 @@ import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.StateChangeListener;
public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, LineInstanceable, InsideColorComponent {

View File

@ -178,9 +178,9 @@ public class Parachute extends RecoveryDevice {
this.diameter = DEFAULT_DIAMETER;
}
// // Set preset parachute drag coefficient
if ((preset.has(ComponentPreset.PARACHUTE_CD)) && preset.get(ComponentPreset.PARACHUTE_CD) > 0){
if ((preset.has(ComponentPreset.CD)) && preset.get(ComponentPreset.CD) > 0){
cdAutomatic = false;
cd = preset.get(ComponentPreset.PARACHUTE_CD);
cd = preset.get(ComponentPreset.CD);
} else {
cdAutomatic = true;
cd = Parachute.DEFAULT_CD;

View File

@ -40,19 +40,19 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
* ^ [[[[[[]]]]]] flangeHeight
* total >||||||<= inner dia ^
* height |||||| v
* v [[[[[[]]]]]] standoff == baseHeight
* v [[[[[[]]]]]] baseHeight / standoff
* ================== ^
* (body)
*
*/
// Note: the reference point for Rail Button Components is in the center bottom of the button.
protected double outerDiameter_m;
protected double totalHeight_m;
protected double innerDiameter_m;
protected double totalHeight_m;
protected double flangeHeight_m;
protected double standoff_m;
protected final static double MINIMUM_STANDOFF= 0.001;
protected double baseHeight_m;
protected double screwHeight_m; // This has no effect at the moment; is for future use.
private double radialDistance_m=0;
protected static final AngleMethod angleMethod = AngleMethod.RELATIVE;
@ -66,7 +66,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
this.totalHeight_m = 0.0097;
this.innerDiameter_m = 0.008;
this.flangeHeight_m = 0.002;
this.setStandoff( 0.002);
this.setBaseHeight(0.002);
this.setInstanceSeparation( this.outerDiameter_m * 6);
this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin"));
super.displayOrder_side = 14; // Order for displaying the component in the 2D side view
@ -75,19 +75,19 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
public RailButton( final double od, final double ht ) {
this();
this.setOuterDiameter( od);
this.setTotalHeight( ht);
this.setOuterDiameter(od);
this.setTotalHeight(ht);
super.displayOrder_side = 14; // Order for displaying the component in the 2D side view
super.displayOrder_back = 11; // Order for displaying the component in the 2D back view
}
public RailButton( final double od, final double id, final double ht, final double flangeThickness, final double _standoff ) {
public RailButton( final double od, final double id, final double ht, final double _flangeHeight, final double _baseHeight ) {
super(AxialMethod.MIDDLE);
this.outerDiameter_m = od;
this.totalHeight_m = ht;
this.innerDiameter_m = id;
this.flangeHeight_m = flangeThickness;
this.setStandoff( _standoff);
this.flangeHeight_m = _flangeHeight;
this.setBaseHeight(_baseHeight);
this.setInstanceSeparation( od*2);
this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin"));
super.displayOrder_side = 14; // Order for displaying the component in the 2D side view
@ -121,13 +121,9 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
return rb1010;
}
public double getStandoff(){
return this.standoff_m;
}
public double getBaseHeight(){
return this.getStandoff();
return this.baseHeight_m;
}
public double getOuterDiameter() {
@ -139,7 +135,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
}
public double getInnerHeight() {
return (this.totalHeight_m - this.flangeHeight_m - this.standoff_m);
return (this.totalHeight_m - this.flangeHeight_m - this.baseHeight_m);
}
public double getTotalHeight() {
@ -149,16 +145,48 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
public double getFlangeHeight() {
return this.flangeHeight_m;
}
public double getScrewHeight() {
return this.screwHeight_m;
}
public void setStandoff(double newStandoff){
public void setBaseHeight(double newBaseHeight){
for (RocketComponent listener : configListeners) {
if (listener instanceof RailButton) {
((RailButton) listener).setStandoff(newStandoff);
((RailButton) listener).setBaseHeight(newBaseHeight);
}
}
this.standoff_m = Math.max( newStandoff, RailButton.MINIMUM_STANDOFF );
this.baseHeight_m = Math.max(newBaseHeight, 0);
this.baseHeight_m = Math.min(this.baseHeight_m, this.totalHeight_m - this.flangeHeight_m);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public void setFlangeHeight(double newFlangeHeight){
for (RocketComponent listener : configListeners) {
if (listener instanceof RailButton) {
((RailButton) listener).setFlangeHeight(newFlangeHeight);
}
}
this.flangeHeight_m = Math.max(newFlangeHeight, 0);
this.flangeHeight_m = Math.min(this.flangeHeight_m, this.totalHeight_m - this.baseHeight_m);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public void setScrewHeight(double height) {
for (RocketComponent listener : configListeners) {
if (listener instanceof RailButton) {
((RailButton) listener).setScrewHeight(height);
}
}
this.screwHeight_m = Math.max(height, 0);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public void setInnerDiameter(double newID ){
@ -168,7 +196,8 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
}
}
this.innerDiameter_m = newID;
this.innerDiameter_m = Math.min(newID, this.outerDiameter_m);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@ -181,7 +210,9 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
}
this.outerDiameter_m = newOD;
setInnerDiameter(this.innerDiameter_m);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@ -192,22 +223,12 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
}
}
this.totalHeight_m = newHeight;
this.totalHeight_m = Math.max(newHeight, this.flangeHeight_m + this.baseHeight_m);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public void setThickness(double newThickness ) {
for (RocketComponent listener : configListeners) {
if (listener instanceof RailButton) {
((RailButton) listener).setThickness(newThickness);
}
}
this.flangeHeight_m = newThickness;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public boolean isAerodynamic(){
// TODO: implement aerodynamics
@ -252,15 +273,17 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
super.setAxialMethod(position);
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
}
@Override
public BoundingBox getInstanceBoundingBox(){
BoundingBox instanceBounds = new BoundingBox();
instanceBounds.update(new Coordinate(0, this.getTotalHeight(), 0));
instanceBounds.update(new Coordinate(0, this.totalHeight_m, 0));
instanceBounds.update(new Coordinate(0, -this.totalHeight_m, 0));
final double r = this.getOuterDiameter();
instanceBounds.update(new Coordinate(r,r,0));
instanceBounds.update(new Coordinate(-r,-r,0));
final double r = this.getOuterDiameter() / 2;
instanceBounds.update(new Coordinate(r, 0, r));
instanceBounds.update(new Coordinate(-r, 0, -r));
return instanceBounds;
}
@ -306,7 +329,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
public double getComponentVolume() {
final double volOuter = Math.PI*Math.pow( outerDiameter_m/2, 2)*flangeHeight_m;
final double volInner = Math.PI*Math.pow( innerDiameter_m/2, 2)*getInnerHeight();
final double volStandoff = Math.PI*Math.pow( outerDiameter_m/2, 2)*standoff_m;
final double volStandoff = Math.PI*Math.pow( outerDiameter_m/2, 2)* baseHeight_m;
return (volOuter+
volInner+
volStandoff);
@ -370,12 +393,12 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
@Override
public Coordinate getComponentCG() {
// Math.PI and density are assumed constant through calculation, and thus may be factored out.
final double volumeFlange = Math.pow( outerDiameter_m/2, 2)*flangeHeight_m;
final double volumeInner = Math.pow( innerDiameter_m/2, 2)*(getInnerHeight());
final double volumeStandoff = Math.pow( outerDiameter_m/2, 2)*this.standoff_m;
final double totalVolume = volumeFlange + volumeInner + volumeStandoff;
final double heightCM = (volumeFlange*( this.totalHeight_m-getFlangeHeight()/2) + volumeInner*( this.standoff_m + this.getInnerHeight()/2) + volumeStandoff*(this.standoff_m/2))/totalVolume;
// Math.PI and density are assumed constant through calculation, and thus may be factored out.
final double volumeBase = Math.pow(outerDiameter_m / 2, 2) * this.baseHeight_m;
final double volumeFlange = Math.pow(outerDiameter_m / 2, 2)* this.flangeHeight_m;
final double volumeInner = Math.pow(innerDiameter_m / 2, 2)* getInnerHeight();
final double totalVolume = volumeFlange + volumeInner + volumeBase;
final double heightCM = (volumeFlange*( this.totalHeight_m-getFlangeHeight()/2) + volumeInner*( this.baseHeight_m + this.getInnerHeight()/2) + volumeBase*(this.baseHeight_m /2))/totalVolume;
if( heightCM > this.totalHeight_m ){
throw new BugException(" bug found while computing the CG of a RailButton: "+this.getName()+"\n height of CG: "+heightCM);
@ -417,4 +440,48 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
return false;
}
@Override
protected void loadFromPreset(ComponentPreset preset) {
super.loadFromPreset(preset);
if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
this.outerDiameter_m = preset.get(ComponentPreset.OUTER_DIAMETER);
}
if (preset.has(ComponentPreset.INNER_DIAMETER)) {
this.innerDiameter_m = preset.get(ComponentPreset.INNER_DIAMETER);
}
if (preset.has(ComponentPreset.HEIGHT)) {
this.totalHeight_m = preset.get(ComponentPreset.HEIGHT);
}
if (preset.has(ComponentPreset.FLANGE_HEIGHT)) {
this.flangeHeight_m = preset.get(ComponentPreset.FLANGE_HEIGHT);
}
if (preset.has(ComponentPreset.BASE_HEIGHT)) {
this.baseHeight_m = preset.get(ComponentPreset.BASE_HEIGHT);
}
if (preset.has(ComponentPreset.CD) && preset.get(ComponentPreset.CD) > 0) {
setCDOverridden(true);
setOverrideCD(preset.get(ComponentPreset.CD));
}
double totalMass = 0;
boolean massOverridden = false;
if (preset.has(ComponentPreset.MASS)) {
massOverridden = true;
totalMass += preset.get(ComponentPreset.MASS);
}
if (preset.has(ComponentPreset.SCREW_MASS)) {
massOverridden = true;
totalMass += preset.get(ComponentPreset.SCREW_MASS);
}
if (preset.has(ComponentPreset.NUT_MASS)) {
massOverridden = true;
totalMass += preset.get(ComponentPreset.NUT_MASS);
}
if (massOverridden) {
setMassOverridden(true);
setOverrideMass(totalMass);
}
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
}

View File

@ -287,6 +287,11 @@ public class Rocket extends ComponentAssembly {
refType = type;
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
}
@Override
public double getLength() {
return selectedConfiguration.getLength();
}
public double getCustomReferenceLength() {
@ -304,6 +309,17 @@ public class Rocket extends ComponentAssembly {
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
}
}
@Override
public double getBoundingRadius() {
double bounding = 0;
for (RocketComponent comp : children) {
if (comp instanceof ComponentAssembly) {
bounding = Math.max(bounding, ((ComponentAssembly) comp).getBoundingRadius());
}
}
return bounding;
}
@ -403,10 +419,12 @@ public class Rocket extends ComponentAssembly {
this.stageMap = r.stageMap;
// these flight configurations need to reference the _this_ Rocket:
this.configSet.reset();
this.configSet.setDefault(new FlightConfiguration(this));
for (FlightConfigurationId key : r.configSet.map.keySet()) {
this.configSet.set(key, new FlightConfiguration(this, key));
}
this.selectedConfiguration = this.configSet.get(r.getSelectedConfiguration().getId());
this.perfectFinish = r.perfectFinish;
@ -496,9 +514,9 @@ public class Rocket extends ComponentAssembly {
// Notify all components first
Iterator<RocketComponent> iterator = this.iterator(true);
while (iterator.hasNext()) {
iterator.next().componentChanged(cce);
RocketComponent next = iterator.next();
next.componentChanged(cce);
}
updateConfigurations();
notifyAllListeners(cce);
@ -538,7 +556,6 @@ public class Rocket extends ComponentAssembly {
}
private void updateConfigurations(){
this.selectedConfiguration.update();
for( FlightConfiguration config : configSet ){
config.update();
}

View File

@ -1010,7 +1010,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
* If the length of a component is settable, the class must define the setter method
* itself.
*/
public final double getLength() {
public double getLength() {
mutex.verify();
return length;
}

View File

@ -0,0 +1,101 @@
package net.sf.openrocket.scripting;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import java.util.*;
import com.oracle.truffle.js.scriptengine.GraalJSScriptEngine;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.HostAccess;
public class GraalJSScriptEngineFactory implements ScriptEngineFactory {
private static final String ENGINE_NAME = "Graal.js";
private static final String LANGUAGE = "ECMAScript";
private static final String LANGUAGE_VERSION = "ECMAScript 262 Edition 11";
private static final String[] NAMES = new String[]{"js", "JS", "JavaScript", "javascript", LANGUAGE, LANGUAGE.toLowerCase(), ENGINE_NAME, ENGINE_NAME.toLowerCase(), "Graal-js", "graal-js", "Graal.JS", "Graal-JS", "GraalJS", "GraalJSPolyglot"};
private static final String[] MIME_TYPES = new String[]{"application/javascript", "application/ecmascript", "text/javascript", "text/ecmascript"};
private static final String[] EXTENSIONS = new String[]{"js", "mjs"};
private static final List names;
private static final List mimeTypes;
private static final List extensions;
public GraalJSScriptEngineFactory() {
}
public ScriptEngine getScriptEngine() {
// https://github.com/oracle/graaljs/blob/master/docs/user/RunOnJDK.md
// https://github.com/oracle/graaljs/blob/master/docs/user/ScriptEngine.md#setting-options-via-bindings
return GraalJSScriptEngine.create(null,
Context.newBuilder("js")
.allowHostAccess(HostAccess.ALL)
.allowHostClassLookup(s -> true)
.option("js.ecmascript-version", "2021"));
}
public String getEngineName() {
return ENGINE_NAME;
}
public String getEngineVersion() {
return ((GraalJSScriptEngine)getScriptEngine()).getPolyglotEngine().getVersion();
}
public List<String> getExtensions() {
return extensions;
}
public String getLanguageVersion() {
return LANGUAGE_VERSION;
}
public String getLanguageName() {
return LANGUAGE;
}
public List<String> getMimeTypes() {
return mimeTypes;
}
public List<String> getNames() {
return names;
}
public String getMethodCallSyntax(final String obj, final String method, final String... args) {
return null;
}
public String getOutputStatement(final String toDisplay) {
return "print(" + toDisplay + ")";
}
public Object getParameter(String key) {
switch (key) {
case "javax.script.name":
return "javascript";
case "javax.script.engine":
return this.getEngineName();
case "javax.script.engine_version":
return this.getEngineVersion();
case "javax.script.language":
return this.getLanguageName();
case "javax.script.language_version":
return this.getLanguageVersion();
default:
return null;
}
}
public String getProgram(final String... statements) {
return null;
}
static {
List<String> nameList = Arrays.asList(NAMES);
List<String> mimeTypeList = Arrays.asList(MIME_TYPES);
List<String> extensionList = Arrays.asList(EXTENSIONS);
names = Collections.unmodifiableList(nameList);
mimeTypes = Collections.unmodifiableList(mimeTypeList);
extensions = Collections.unmodifiableList(extensionList);
}
}

View File

@ -0,0 +1,300 @@
/*
* This is a replacement for the ScriptEngineManager which gets around and issue with the sun.misc.ServiceConfigurationError
* which has been removed in Java 9+. If using the ScriptEngineManager from the script-api*.jar then the sun.misc throws
* a ClassNotFoundException.
*/
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package net.sf.openrocket.scripting;
import javax.script.*;
import java.util.*;
import java.security.*;
import java.util.ServiceLoader;
import java.util.ServiceConfigurationError;
/**
* The <code>ScriptEngineManager</code> implements a discovery and instantiation
* mechanism for <code>ScriptEngine</code> classes and also maintains a
* collection of key/value pairs storing state shared by all engines created
* by the Manager. This class uses the service provider mechanism described in the
* {@link java.util.ServiceLoader} class to enumerate all the
* implementations of <code>ScriptEngineFactory</code>. <br><br>
* The <code>ScriptEngineManager</code> provides a method to return a list of all these factories
* as well as utility methods which look up factories on the basis of language name, file extension
* and mime type.
* <p>
* The <code>Bindings</code> of key/value pairs, referred to as the "Global Scope" maintained
* by the manager is available to all instances of <code>ScriptEngine</code> created
* by the <code>ScriptEngineManager</code>. The values in the <code>Bindings</code> are
* generally exposed in all scripts.
*
* @author Mike Grogan
* @author A. Sundararajan
* @since 1.6
*/
public class ScriptEngineManagerRedux {
private static final boolean DEBUG = false;
/**
* The effect of calling this constructor is the same as calling
* <code>ScriptEngineManager(Thread.currentThread().getContextClassLoader())</code>.
*
* @see java.lang.Thread#getContextClassLoader
*/
public ScriptEngineManagerRedux() {
init(Thread.currentThread().getContextClassLoader());
}
/**
* This constructor loads the implementations of
* <code>ScriptEngineFactory</code> visible to the given
* <code>ClassLoader</code> using the service provider mechanism.<br><br>
* If loader is <code>null</code>, the script engine factories that are
* bundled with the platform are loaded. <br>
*
* @param loader ClassLoader used to discover script engine factories.
*/
public ScriptEngineManagerRedux(ClassLoader loader) {
init(loader);
}
/**
* Gets the value for the specified key in the Global Scope
* @param key The key whose value is to be returned.
* @return The value for the specified key.
*/
public Object get(String key) {
return _globalScope.get(key);
}
/**
* <code>getBindings</code> returns the value of the <code>globalScope</code> field.
* ScriptEngineManager sets this <code>Bindings</code> as global bindings for
* <code>ScriptEngine</code> objects created by it.
*
* @return The globalScope field.
*/
public Bindings getBindings() {
return _globalScope;
}
/**
* Looks up and creates a <code>ScriptEngine</code> for a given name.
* The algorithm first searches for a <code>ScriptEngineFactory</code> that has been
* registered as a handler for the specified name using the <code>registerEngineName</code>
* method.
* <br><br> If one is not found, it searches the set of <code>ScriptEngineFactory</code> instances
* stored by the constructor for one with the specified name. If a <code>ScriptEngineFactory</code>
* is found by either method, it is used to create instance of <code>ScriptEngine</code>.
* @param shortName The short name of the <code>ScriptEngine</code> implementation.
* returned by the <code>getNames</code> method of its <code>ScriptEngineFactory</code>.
* @return A <code>ScriptEngine</code> created by the factory located in the search. Returns null
* if no such factory was found. The <code>ScriptEngineManager</code> sets its own <code>globalScope</code>
* <code>Bindings</code> as the <code>GLOBAL_SCOPE</code> <code>Bindings</code> of the newly
* created <code>ScriptEngine</code>.
* @throws NullPointerException if shortName is null.
*/
private Map<String, ScriptEngineFactory> _factoriesByName = new HashMap<>();
public synchronized ScriptEngine getEngineByName(String shortName) {
if (shortName == null) {
throw new NullPointerException();
}
String key = shortName.toLowerCase();
if (_factoriesByName.containsKey(key)) {
return getEngineByFactory(_factoriesByName.get(key));
}
// Look for registered name first
ScriptEngineFactory factoryNamed;
if (null != (factoryNamed = _nameAssociations.get(key))) {
try {
_factoriesByName.put(key, factoryNamed);
return getEngineByFactory(factoryNamed);
} catch (Exception exp) {
if (DEBUG) {
exp.printStackTrace();
}
}
}
Optional<String> factoryName;
List<String> names;
for (ScriptEngineFactory factory : _scriptEngineFactories) {
try {
factoryName = factory.getNames().stream().filter(l -> l.equalsIgnoreCase(shortName)).findFirst();
if (factoryName.isPresent()) {
_factoriesByName.put(key, factory);
return getEngineByFactory(factory);
}
} catch (Exception exp) {
if (DEBUG) {
exp.printStackTrace();
}
}
}
return null;
}
/**
* Returns a list whose elements are instances of all the <code>ScriptEngineFactory</code> classes
* found by the discovery mechanism.
* @return List of all discovered <code>ScriptEngineFactory</code>s.
*/
public synchronized List<ScriptEngineFactory> getEngineFactories() {
return List.copyOf(_scriptEngineFactories);
}
/**
* Sets the specified key/value pair in the Global Scope.
* @param key Key to set
* @param value Value to set.
* @throws NullPointerException if key is null.
* @throws IllegalArgumentException if key is empty string.
*/
public void put(String key, Object value) {
_globalScope.put(key, value);
}
/**
* Registers a <code>ScriptEngineFactory</code> to handle a language
* name. Overrides any such association found using the Discovery mechanism.
* @param name The name to be associated with the <code>ScriptEngineFactory</code>.
* @param factory The class to associate with the given name.
* @throws NullPointerException if any of the parameters is null.
*/
public void registerEngineName(String name, ScriptEngineFactory factory) {
if (name == null || factory == null) {
throw new NullPointerException();
}
_nameAssociations.put(name.toLowerCase(), factory);
}
/**
* <code>setBindings</code> stores the specified <code>Bindings</code>
* in the <code>globalScope</code> field. ScriptEngineManager sets this
* <code>Bindings</code> as global bindings for <code>ScriptEngine</code>
* objects created by it.
*
* @param bindings The specified <code>Bindings</code>
* @throws IllegalArgumentException if bindings is null.
*/
public void setBindings(Bindings bindings) {
if (bindings == null) {
throw new IllegalArgumentException("Global scope cannot be null.");
}
_globalScope = bindings;
}
private ScriptEngine getEngineByFactory(ScriptEngineFactory factory) {
if (factory == null) {
return null;
}
ScriptEngine engine = factory.getScriptEngine();
engine.setBindings(getBindings(), ScriptContext.GLOBAL_SCOPE);
return engine;
}
private ServiceLoader<ScriptEngineFactory> getServiceLoader(final ClassLoader loader) {
if (loader != null) {
return ServiceLoader.load(ScriptEngineFactory.class, loader);
} else {
return ServiceLoader.loadInstalled(ScriptEngineFactory.class);
}
}
private void init(final ClassLoader loader) {
_scriptEngineFactories = new TreeSet<>(Comparator.comparing(
ScriptEngineFactory::getEngineName,
Comparator.nullsLast(Comparator.naturalOrder()))
);
initEngines(loader);
}
private void initEngines(final ClassLoader loader) {
Iterator<ScriptEngineFactory> itr;
try {
ServiceLoader<ScriptEngineFactory> loaders = AccessController.doPrivileged(
new PrivilegedAction<ServiceLoader<ScriptEngineFactory>>() {
@Override
public ServiceLoader<ScriptEngineFactory> run() {
return getServiceLoader(loader);
}
});
itr = loaders.iterator();
} catch (ServiceConfigurationError err) {
// } catch (Exception err) {
System.err.println("Can't find ScriptEngineFactory providers: " + err.getMessage());
if (DEBUG) {
err.printStackTrace();
}
// do not throw any exception here. user may want to
// manage his/her own factories using this manager
// by explicit registration (by registerXXX) methods.
return;
}
try {
while (itr.hasNext()) {
try {
ScriptEngineFactory factory = itr.next();
_scriptEngineFactories.add(factory);
} catch (ServiceConfigurationError err) {
// } catch (Exception err) {
System.err.println("ScriptEngineManager providers.next(): " + err.getMessage());
if (DEBUG) {
err.printStackTrace();
}
// one factory failed, but check other factories...
}
}
} catch (ServiceConfigurationError err) {
// } catch (Exception err) {
System.err.println("ScriptEngineManager providers.hasNext(): " + err.getMessage());
if (DEBUG) {
err.printStackTrace();
}
// do not throw any exception here. user may want to
// manage his/her own factories using this manager
// by explicit registratation (by registerXXX) methods.
}
}
/** Set of script engine factories discovered. */
private TreeSet<ScriptEngineFactory> _scriptEngineFactories;
/** Map of engine name to script engine factory. */
private HashMap<String, ScriptEngineFactory> _nameAssociations = new HashMap<>();
/** Global bindings associated with script engines created by this manager. */
private Bindings _globalScope = new SimpleBindings();
}

View File

@ -130,8 +130,8 @@ public class BasicEventSimulationEngine implements SimulationEngine {
double oldAlt = currentStatus.getRocketPosition().z;
if (SimulationListenerHelper.firePreStep(currentStatus)) {
// Step at most to the next event
double maxStepTime = Double.MAX_VALUE;
// Step at most to the next event. If there is no next event, don't step time
double maxStepTime = 0.0;
FlightEvent nextEvent = currentStatus.getEventQueue().peek();
if (nextEvent != null) {
maxStepTime = MathUtil.max(nextEvent.getTime() - currentStatus.getSimulationTime(), 0.001);

View File

@ -20,5 +20,6 @@ public class GroundStepper extends AbstractSimulationStepper {
@Override
public void step(SimulationStatus status, double timeStep) throws SimulationException {
log.trace("step: position=" + status.getRocketPosition() + ", velocity=" + status.getRocketVelocity());
status.setSimulationTime(status.getSimulationTime() + timeStep);
}
}

View File

@ -2,7 +2,6 @@ package net.sf.openrocket.simulation.extension.impl;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import net.sf.openrocket.aerodynamics.Warning;
@ -91,8 +90,7 @@ public class ScriptingExtension extends AbstractSimulationExtension {
SimulationListener getListener() throws SimulationException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName(getLanguage());
ScriptEngine engine = util.getEngineByName(getLanguage());
if (engine == null) {
throw new SimulationException("Your JRE does not support the scripting language '" + getLanguage() + "'");
}

View File

@ -4,14 +4,14 @@ import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
import java.util.prefs.BackingStoreException;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import net.sf.openrocket.scripting.ScriptEngineManagerRedux;
import net.sf.openrocket.scripting.GraalJSScriptEngineFactory;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.BugException;
@ -22,22 +22,34 @@ import com.google.inject.Inject;
* Utility class used by the scripting extension and its configurator.
*/
public class ScriptingUtil {
static final String NODE_ID = ScriptingExtension.class.getCanonicalName();
private static final List<String> DEFAULT_TRUSTED_HASHES = Arrays.asList(
private static final List<String> DEFAULT_TRUSTED_HASHES = List.of(
// Roll control script in roll control example file:
"SHA-256:9bf364ce4d4a75f09b29178bf9d6872b232084f73dae20dc7b5b073e54e95a42"
);
);
/** The name to be chosen from a list of alternatives. If not found, will use the default name. */
private static final List<String> PREFERRED_LANGUAGE_NAMES = Arrays.asList("JavaScript");
private static final List<String> PREFERRED_LANGUAGE_NAMES = List.of("JavaScript");
private static ScriptEngineManagerRedux manager;
@Inject
Preferences prefs;
public ScriptingUtil() {
if (manager == null) {
// using the ScriptEngineManger from javax.script package pulls in the sun.misc.ServiceConfigurationError
// which is removed in Java 9+ which causes a ClassNotFoundException to be thrown.
manager = new ScriptEngineManagerRedux();
manager.registerEngineName("Javascript", new GraalJSScriptEngineFactory());
}
}
public ScriptEngine getEngineByName(String shortName) {
return manager.getEngineByName(shortName);
}
/**
* Return the preferred internal language name based on a script language name.
@ -48,38 +60,23 @@ public class ScriptingUtil {
if (language == null) {
return null;
}
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName(language);
if (engine == null) {
return null;
}
return getLanguage(engine.getFactory());
return getLanguageByFactory(engine.getFactory());
}
public List<String> getLanguages() {
List<String> langs = new ArrayList<String>();
ScriptEngineManager manager = new ScriptEngineManager();
List<String> languages = new ArrayList<>();
for (ScriptEngineFactory factory : manager.getEngineFactories()) {
langs.add(getLanguage(factory));
languages.add(getLanguageByFactory(factory));
}
return langs;
return languages;
}
private String getLanguage(ScriptEngineFactory factory) {
for (String name : factory.getNames()) {
if (PREFERRED_LANGUAGE_NAMES.contains(name)) {
return name;
}
}
return factory.getLanguageName();
}
/**
* Test whether the user has indicated this script to be trusted,
* or if it is an internally trusted script.
@ -122,7 +119,16 @@ public class ScriptingUtil {
throw new BugException(e);
}
}
private String getLanguageByFactory(ScriptEngineFactory factory) {
for (String name : factory.getNames()) {
if (PREFERRED_LANGUAGE_NAMES.contains(name)) {
return name;
}
}
return factory.getLanguageName();
}
static String normalize(String script) {
return script.replaceAll("\r", "").trim();
@ -132,10 +138,8 @@ public class ScriptingUtil {
/*
* NOTE: Hash length must be max 80 chars, the max length of a key in a Properties object.
*/
String output;
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-256");
digest.update(language.getBytes(StandardCharsets.UTF_8));
@ -152,5 +156,4 @@ public class ScriptingUtil {
return digest.getAlgorithm() + ":" + output;
}
}

View File

@ -35,8 +35,7 @@ public class RollControlListener extends AbstractSimulationListener {
// Maximum control fin angle (rad)
private static final double MAX_ANGLE = 15 * Math.PI / 180;
/*
* PID parameters
*
@ -47,29 +46,22 @@ public class RollControlListener extends AbstractSimulationListener {
private static final double KP = 0.007;
private static final double KI = 0.2;
private double rollrate;
private double rollRate;
private double prevTime = 0;
private double intState = 0;
private double finPosition = 0;
@Override
public FlightConditions postFlightConditions(SimulationStatus status, FlightConditions flightConditions) {
// Store the current roll rate for later use
rollrate = flightConditions.getRollRate();
rollRate = flightConditions.getRollRate();
return null;
}
@Override
public void postStep(SimulationStatus status) throws SimulationException {
// Activate PID controller only after a specific time
if (status.getSimulationTime() < START_TIME) {
prevTime = status.getSimulationTime();
@ -87,23 +79,20 @@ public class RollControlListener extends AbstractSimulationListener {
if (finset == null) {
throw new SimulationException("A fin set with name '" + CONTROL_FIN_NAME + "' was not found");
}
// Determine time step
double deltaT = status.getSimulationTime() - prevTime;
prevTime = status.getSimulationTime();
// PID controller
double error = SETPOINT - rollrate;
double error = SETPOINT - rollRate;
double p = KP * error;
intState += error * deltaT;
double i = KI * intState;
double value = p + i;
// Clamp the fin angle between -MAX_ANGLE and MAX_ANGLE
if (Math.abs(value) > MAX_ANGLE) {
System.err.printf("Attempting to set angle %.1f at t=%.3f, clamping.\n",
@ -111,7 +100,6 @@ public class RollControlListener extends AbstractSimulationListener {
value = MathUtil.clamp(value, -MAX_ANGLE, MAX_ANGLE);
}
// Limit the fin turn rate
if (finPosition < value) {
finPosition = Math.min(finPosition + TURNRATE * deltaT, value);
@ -122,6 +110,5 @@ public class RollControlListener extends AbstractSimulationListener {
// Set the control fin cant and store the data
finset.setCantAngle(finPosition);
status.getFlightData().setValue(FIN_CANT_TYPE, finPosition);
}
}

View File

@ -63,11 +63,15 @@ public abstract class Preferences implements ChangeSource {
public static final String MOTOR_DIAMETER_FILTER = "MotorDiameterMatch";
public static final String MOTOR_HIDE_SIMILAR = "MotorHideSimilar";
public static final String MOTOR_HIDE_UNAVAILABLE = "MotorHideUnavailable";
public static final String MATCH_FORE_DIAMETER = "MatchForeDiameter";
public static final String MATCH_AFT_DIAMETER = "MatchAftDiameter";
// Node names
public static final String PREFERRED_THRUST_CURVE_MOTOR_NODE = "preferredThrustCurveMotors";
private static final String AUTO_OPEN_LAST_DESIGN = "AUTO_OPEN_LAST_DESIGN";
private static final String OPEN_LEFTMOST_DESIGN_TAB = "OPEN_LEFTMOST_DESIGN_TAB";
private static final String SHOW_MARKERS = "SHOW_MARKERS";
private static final String SHOW_ROCKSIM_FORMAT_WARNING = "SHOW_ROCKSIM_FORMAT_WARNING";
//Preferences related to 3D graphics
@ -469,7 +473,64 @@ public abstract class Preferences implements ChangeSource {
public final boolean isAlwaysOpenLeftmostTab() {
return this.getBoolean(OPEN_LEFTMOST_DESIGN_TAB, false);
}
/**
* Set whether pod set/booster markers should only be displayed when the pod set/booster is selected.
* @param enabled true if pod set/booster markers should only be displayed when the pod set/booster is selected,
* false if they should be displayed permanently.
*/
public final void setShowMarkers(boolean enabled) {
this.putBoolean(SHOW_MARKERS, enabled);
}
/**
* Answer if pod set/booster markers should only be displayed when the pod set/booster is selected
*
* @return true if pod set/booster markers should only be displayed when the pod set/booster is selected,
* false if they should be displayed permanently.
*/
public final boolean isShowMarkers() {
return this.getBoolean(SHOW_MARKERS, false);
}
/**
* Set whether the component preset chooser dialog should filter by fore diameter when the window is opened.
* @param enabled true if the fore diameter filter should be enabled,
* false if it should be disabled.
*/
public final void setMatchForeDiameter(boolean enabled) {
this.putBoolean(MATCH_FORE_DIAMETER, enabled);
}
/**
* Answer if the component preset chooser dialog should filter by fore diameter when the window is opened.
*
* @return true if the fore diameter filter should be enabled,
* false if it should be disabled.
*/
public final boolean isMatchForeDiameter() {
return this.getBoolean(MATCH_FORE_DIAMETER, true);
}
/**
* Set whether the component preset chooser dialog should filter by aft diameter when the window is opened.
* @param enabled true if the aft diameter filter should be enabled,
* false if it should be disabled.
*/
public final void setMatchAftDiameter(boolean enabled) {
this.putBoolean(MATCH_AFT_DIAMETER, enabled);
}
/**
* Answer if the component preset chooser dialog should filter by aft diameter when the window is opened.
*
* @return true if the aft diameter filter should be enabled,
* false if it should be disabled.
*/
public final boolean isMatchAftDiameter() {
return this.getBoolean(MATCH_AFT_DIAMETER, true);
}
/**
* Return the OpenRocket unique ID.
*

View File

@ -19,6 +19,8 @@ import org.junit.Test;
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
*/
public class DisableStageTest extends BaseTestCase {
private final double delta = 0.08; // 8 % error margin (simulations are not exact)
/**
* Tests that the simulation results are correct when a single stage is deactivated and re-activated.
*/
@ -54,7 +56,6 @@ public class DisableStageTest extends BaseTestCase {
simDisabled.getActiveConfiguration().setAllStages(); // Re-enable all stages.
double delta = 0.05; // 5 % error margin (simulations are not exact)
compareSims(simOriginal, simDisabled, simulationListener, delta);
}
@ -84,7 +85,6 @@ public class DisableStageTest extends BaseTestCase {
SimulationListener simulationListener = new AbstractSimulationListener();
double delta = 0.05; // 5 % error margin (simulations are not exact)
compareSims(simRemoved, simDisabled, simulationListener, delta);
//// Test re-enableing the stage.
@ -175,7 +175,6 @@ public class DisableStageTest extends BaseTestCase {
SimulationListener simulationListener = new AbstractSimulationListener();
double delta = 0.05; // 5 % error margin (simulations are not exact)
compareSims(simRemoved, simDisabled, simulationListener, delta);
//// Test re-enableing the stage.
@ -243,7 +242,6 @@ public class DisableStageTest extends BaseTestCase {
simDisabled.getActiveConfiguration().setAllStages();
double delta = 0.05; // 5 % error margin (simulations are not exact)
compareSims(simOriginal, simDisabled, simulationListener, delta);
}

View File

@ -1,6 +1,6 @@
name: openrocket
adopt-info: openrocket
grade: devel
grade: stable
summary: A free, fully featured model rocket simulator.
description: |
OpenRocket is a free, fully featured model rocket simulator that allows you
@ -77,6 +77,7 @@ parts:
prime:
- -usr/lib/jvm/java-*/lib/security/cacerts
- -usr/lib/jvm/java-*/jre/lib/security/cacerts
- -usr/lib/jvm/java-*/lib/security/blacklisted.certs
launcher:
plugin: dump

View File

@ -19,6 +19,7 @@
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.inject.jar"/>
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.json-1.1.3.jar"/>
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.json-api-1.1.3.jar"/>
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.activation-api.2.3.1.jar"/>
<classpathentry kind="lib" path="/OpenRocket Core/resources"/>
<classpathentry kind="lib" path="resources"/>
<classpathentry kind="lib" path="lib/miglayout-4.0-swing.jar" sourcepath="reference/miglayout-4.0-sources.jar"/>

View File

@ -245,5 +245,50 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../core/lib/icu4j-71.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../core/lib/graal-sdk-22.1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../core/lib/js-22.1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../core/lib/js-scriptengine-22.1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../core/lib/truffle-api-22.1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>

View File

@ -99,6 +99,11 @@
<zipfileset src="${core.dir}/lib/guice-4.2.3-no_aop.jar" />
<zipfileset src="${core.dir}/lib/aopalliance.jar"/>
<zipfileset src="${core.dir}/lib/commonmark-0.19.0.jar"/>
<zipfileset src="${core.dir}/lib/icu4j-71.1.jar"/>
<zipfileset src="${core.dir}/lib/js-22.1.0.1.jar"/>
<zipfileset src="${core.dir}/lib/graal-sdk-22.1.0.1.jar"/>
<zipfileset src="${core.dir}/lib/js-scriptengine-22.1.0.1.jar"/>
<zipfileset src="${core.dir}/lib/truffle-api-22.1.0.1.jar"/>
<zipfileset src="${core.dir}/lib/script-api-1.0.jar"/>
<zipfileset src="${lib.dir}/iText-5.0.2.jar"/>
<zipfileset src="${core.dir}/lib/istack-commons-runtime.jar"/>
@ -149,7 +154,7 @@
depends="build">
<for param="vendor-dir">
<dirset dir="${resources-src.dir}/datafiles/rocksim_components"
<dirset dir="${resources-src.dir}/datafiles/rocksim_src"
includes="*"/>
<sequential>
<propertyregex property="vendor"

@ -1 +1 @@
Subproject commit 860757167c4835a7bb960a4cbb52b06f3309791c
Subproject commit 4c3604313f0cc8f52274c8fa07e4970e6bfaa273

View File

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OpenRocketComponent>
<Version>0.1</Version>
<Materials>
<Material UnitsOfMeasure="kg/m">
<Name>Delrin</Name>
<Density>1420</Density>
<Type>BULK</Type>
</Material>
<Material UnitsOfMeasure="kg/m">
<Name>Nylon</Name>
<Density>1150</Density>
<Type>BULK</Type>
</Material>
</Materials>
<Components>
<RailButton>
<Manufacturer>Binder Design-Rail Button Supply House</Manufacturer>
<PartNumber>Std 1010 RB</PartNumber>
<Description>Standard 1010 Rail Button, Countersunk 8-32 Screw, and T-Nut</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">0.4375</OuterDiameter>
<InnerDiameter Unit="in">0.2285</InnerDiameter>
<Height Unit="in">0.2975</Height>
<BaseHeight Unit="in">0.0730</BaseHeight>
<FlangeHeight Unit="in">0.0730</FlangeHeight>
<ScrewHeight Unit="in">0.0000</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">0.445</Mass>
<ScrewMass Unit="g">1.395</ScrewMass>
<NutMass Unit="g">1.025</NutMass>
</RailButton>
<RailButton>
<Manufacturer>Binder Design-Rail Button Supply House</Manufacturer>
<PartNumber>Std 1515 RB</PartNumber>
<Description>Standard 1515 Rail Button, Countersunk 10-32 Screw, and T-Nut</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">0.6200</OuterDiameter>
<InnerDiameter Unit="in">0.2995</InnerDiameter>
<Height Unit="in">.4495</Height>
<BaseHeight Unit="in">0.125</BaseHeight>
<FlangeHeight Unit="in">0.125</FlangeHeight>
<ScrewHeight Unit="in">0.0000</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">1.465</Mass>
<ScrewMass Unit="g">3.365</ScrewMass>
<NutMass Unit="g">2.675</NutMass>
</RailButton>
<RailButton>
<Manufacturer>Rail-Buttons.com</Manufacturer>
<PartNumber>RB-Micro</PartNumber>
<Description>2 Piece Micro Rail Button with 2-56 Screw (10mm Rail)</Description>
<Material Type="BULK">Nylon</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">.1650</OuterDiameter>
<InnerDiameter Unit="in">.1195</InnerDiameter>
<Height Unit="in">0.1595</Height>
<BaseHeight Unit="in">0.041</BaseHeight>
<FlangeHeight Unit="in">0.0000</FlangeHeight>
<ScrewHeight Unit="in">0.0465</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">0.01</Mass>
<ScrewMass Unit="g">0.04</ScrewMass>
<NutMass Unit="g"></NutMass>
</RailButton>
<RailButton>
<Manufacturer>Rail-Buttons.com</Manufacturer>
<PartNumber>1PMB</PartNumber>
<Description>1 Piece Mini Rail Button with Countersunk 6-32 Screw</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">.249</OuterDiameter>
<InnerDiameter Unit="in">.193</InnerDiameter>
<Height Unit="in">0.205</Height>
<BaseHeight Unit="in">0.0380</BaseHeight>
<FlangeHeight Unit="in">0.0380</FlangeHeight>
<ScrewHeight Unit="in">0.0000</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">0.090</Mass>
<ScrewMass Unit="g">0.415</ScrewMass>
<NutMass Unit="g"></NutMass>
</RailButton>
<RailButton>
<Manufacturer>Rail-Buttons.com</Manufacturer>
<PartNumber>RB-10-D</PartNumber>
<Description>3 Piece 1010 Rail Button with 8-32 Screw</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">.278</OuterDiameter>
<InnerDiameter Unit="in">.154</InnerDiameter>
<Height Unit="in">0.270</Height>
<BaseHeight Unit="in">0.060</BaseHeight>
<FlangeHeight Unit="in">0.060</FlangeHeight>
<ScrewHeight Unit="in">0.115</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">0.305</Mass>
<ScrewMass Unit="g">1.715</ScrewMass>
<NutMass Unit="g"></NutMass>
</RailButton>
<RailButton>
<Manufacturer>Rail-Buttons.com</Manufacturer>
<PartNumber>1P1010DLX</PartNumber>
<Description>1 Piece 1010 Rail Button with Countersunk 8-32 Screw</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">.3725</OuterDiameter>
<InnerDiameter Unit="in">.2480</InnerDiameter>
<Height Unit="in">0.305</Height>
<BaseHeight Unit="in">0.078</BaseHeight>
<FlangeHeight Unit="in">0.078</FlangeHeight>
<ScrewHeight Unit="in">0.0000</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">0.320</Mass>
<ScrewMass Unit="g">1.235</ScrewMass>
<NutMass Unit="g"></NutMass>
</RailButton>
<RailButton>
<Manufacturer>Rail-Buttons.com</Manufacturer>
<PartNumber>RB1515S</PartNumber>
<Description>1 Piece 1515 Rail Button, Countersunk 10-32 Screw, and T-Nut</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">0.49</OuterDiameter>
<InnerDiameter Unit="in">0.29</InnerDiameter>
<Height Unit="in">0.56</Height>
<BaseHeight Unit="in">0.1875</BaseHeight>
<FlangeHeight Unit="in">0.1875</FlangeHeight>
<ScrewHeight Unit="in">0.0000</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">1.355</Mass>
<ScrewMass Unit="g">2.720</ScrewMass>
<NutMass Unit="g"></NutMass>
</RailButton>
</Components>
</OpenRocketComponent>

View File

@ -5,17 +5,14 @@ import java.util.List;
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
import javax.swing.SwingUtilities;
import net.sf.openrocket.database.ComponentPresetDatabase;
import net.sf.openrocket.gui.configdialog.RocketComponentConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.gui.configdialog.RocketComponentConfig;
import net.sf.openrocket.database.Database;
import net.sf.openrocket.database.DatabaseListener;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.dialogs.preset.ComponentPresetChooserDialog;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.Markers;
import net.sf.openrocket.preset.ComponentPreset;
@ -30,8 +27,7 @@ public class PresetModel extends AbstractListModel implements ComboBoxModel, Com
private static final Logger log = LoggerFactory.getLogger(PresetModel.class);
private static final Translator trans = Application.getTranslator();
private static final String NONE_SELECTED = trans.get("lbl.select");
private static final String SELECT_DATABASE = trans.get("lbl.database");
private static final String NONE_SELECTED = String.format("<html><i>%s</i></html>", trans.get("PresetModel.lbl.custompreset"));
private final Component parent;
private final RocketComponent component;
@ -51,7 +47,7 @@ public class PresetModel extends AbstractListModel implements ComboBoxModel, Com
@Override
public int getSize() {
return presets.size() + 2;
return presets.size() + 1;
}
@Override
@ -59,9 +55,6 @@ public class PresetModel extends AbstractListModel implements ComboBoxModel, Com
if (index == 0) {
return NONE_SELECTED;
}
if (index == getSize() - 1) {
return SELECT_DATABASE;
}
return presets.get(index - 1);
}
@ -73,21 +66,6 @@ public class PresetModel extends AbstractListModel implements ComboBoxModel, Com
throw new BugException("item is null");
} else if (item.equals(NONE_SELECTED)) {
component.clearPreset();
} else if (item.equals(SELECT_DATABASE)) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
((ComponentPresetDatabase) Application.getComponentPresetDao()).addDatabaseListener(PresetModel.this);
ComponentPresetChooserDialog dialog =
new ComponentPresetChooserDialog(SwingUtilities.getWindowAncestor(parent), component);
dialog.setVisible(true);
ComponentPreset preset = dialog.getSelectedComponentPreset();
if (preset != null) {
setSelectedItem(preset);
}
((ComponentPresetDatabase) Application.getComponentPresetDao()).removeChangeListener(PresetModel.this);
}
});
} else {
document.addUndoPosition("Use Preset " + component.getComponentName());
component.loadPreset((ComponentPreset) item);

View File

@ -1,18 +1,24 @@
package net.sf.openrocket.gui.configdialog;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import javax.swing.JDialog;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.main.BasicFrame;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.gui.util.WindowLocationUtil;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
@ -230,8 +236,9 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis
* @param document the document to configure.
* @param component the component to configure.
* @param rememberPreviousTab if true, the previous tab will be remembered and used for the new dialog
* @param includeUndoModify if true, include a 'Modify component' undo action
*/
public static void showDialog(Window parent, OpenRocketDocument document, RocketComponent component, boolean rememberPreviousTab) {
public static void showDialog(Window parent, OpenRocketDocument document, RocketComponent component, boolean rememberPreviousTab, boolean includeUndoModify) {
if (dialog != null) {
// Don't remember the previous tab for rockets or stages, because this will leave you in the override tab for
// the next component, which is generally not what you want.
@ -256,15 +263,32 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis
dialog = new ComponentConfigDialog(parent, document, component);
dialog.setVisible(true);
if (parent instanceof BasicFrame && BasicFrame.getStartupFrame() == parent) {
WindowLocationUtil.moveIfOutsideOfParentMonitor(dialog, parent);
}
////Modify
if (component.getConfigListeners().size() == 0) {
document.addUndoPosition(trans.get("ComponentCfgDlg.Modify") + " " + component.getComponentName());
} else {
document.addUndoPosition(trans.get("ComponentCfgDlg.ModifyComponents"));
if (includeUndoModify) {
if (component.getConfigListeners().size() == 0) {
document.addUndoPosition(trans.get("ComponentCfgDlg.Modify") + " " + component.getComponentName());
} else {
document.addUndoPosition(trans.get("ComponentCfgDlg.ModifyComponents"));
}
}
}
/**
* A singleton configuration dialog. Will create and show a new dialog if one has not
* previously been used, or update the dialog and show it if a previous one exists.
*
* @param document the document to configure.
* @param component the component to configure.
* @param rememberPreviousTab if true, the previous tab will be remembered and used for the new dialog
*/
public static void showDialog(Window parent, OpenRocketDocument document, RocketComponent component, boolean rememberPreviousTab) {
ComponentConfigDialog.showDialog(parent, document, component, rememberPreviousTab, true);
}
/**
* A singleton configuration dialog. Will create and show a new dialog if one has not
* previously been used, or update the dialog and show it if a previous one exists.

View File

@ -81,6 +81,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
private Point dragPoint = null;
private FinPointFigure figure = null;
private ScaleScrollPane figurePane = null;
private ScaleSelector selector;
public FreeformFinSetConfig(OpenRocketDocument d, RocketComponent component, JDialog parent) {
@ -219,7 +220,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
// Create the figure
figure = new FinPointFigure(finset);
ScaleScrollPane figurePane = new FinPointScrollPane( figure);
figurePane = new FinPointScrollPane( figure);
// Create the table
tableModel = new FinPointTableModel();
@ -392,9 +393,10 @@ public class FreeformFinSetConfig extends FinSetConfig {
}
figure.updateFigure();
}
revalidate();
repaint();
if (figurePane != null) {
figurePane.revalidate();
}
}
private class FinPointScrollPane extends ScaleScrollPane {
@ -408,8 +410,6 @@ public class FreeformFinSetConfig extends FinSetConfig {
@Override
public void mousePressed(MouseEvent event) {
int mods = event.getModifiersEx();
final FreeformFinSet finset = (FreeformFinSet) component;
final int pressIndex = getPoint(event);

View File

@ -29,13 +29,6 @@ public class RailButtonConfig extends RocketComponentConfig {
public RailButtonConfig( OpenRocketDocument document, RocketComponent component, JDialog parent) {
super(document, component, parent);
// For DEBUG purposes
// if( component instanceof AxialStage ){
// System.err.println(" Dumping AxialStage tree info for devel / debugging.");
// System.err.println(component.toDebugTree());
// }
//// General and General properties
tabbedPane.insertTab( trans.get("RailBtnCfg.tab.General"), null, buttonTab( (RailButton)component ), trans.get("RailBtnCfg.tab.GeneralProp"), 0);
@ -59,6 +52,33 @@ public class RailButtonConfig extends RocketComponentConfig {
panel.add(new UnitSelector(ODModel), "growx");
panel.add(new BasicSlider(ODModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
}
{ //// Inner Diameter
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.InnerDiam")));
DoubleModel IDModel = new DoubleModel(component, "InnerDiameter", UnitGroup.UNITS_LENGTH, 0);
JSpinner IDSpinner = new JSpinner(IDModel.getSpinnerModel());
IDSpinner.setEditor(new SpinnerEditor(IDSpinner));
panel.add(IDSpinner, "growx");
panel.add(new UnitSelector(IDModel), "growx");
panel.add(new BasicSlider(IDModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap para");
}
{ //// Base Height
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.BaseHeight")));
DoubleModel heightModel = new DoubleModel(component, "BaseHeight", UnitGroup.UNITS_LENGTH, 0);
JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel());
heightSpinner.setEditor(new SpinnerEditor(heightSpinner));
panel.add(heightSpinner, "growx");
panel.add(new UnitSelector(heightModel), "growx");
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
}
{ //// Flange Height
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.FlangeHeight")));
DoubleModel heightModel = new DoubleModel(component, "FlangeHeight", UnitGroup.UNITS_LENGTH, 0);
JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel());
heightSpinner.setEditor(new SpinnerEditor(heightSpinner));
panel.add(heightSpinner, "growx");
panel.add(new UnitSelector(heightModel), "growx");
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
}
{ //// Height
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.TotalHeight")));
DoubleModel heightModel = new DoubleModel(component, "TotalHeight", UnitGroup.UNITS_LENGTH, 0);
@ -66,7 +86,7 @@ public class RailButtonConfig extends RocketComponentConfig {
heightSpinner.setEditor(new SpinnerEditor(heightSpinner));
panel.add(heightSpinner, "growx");
panel.add(new UnitSelector(heightModel), "growx");
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap para");
}
{ //// Angular Position:
@ -79,14 +99,17 @@ public class RailButtonConfig extends RocketComponentConfig {
panel.add(new BasicSlider( angleModel.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap");
}
primary.add(panel, "grow, gapright 201p");
panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
{ //// Position relative to:
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.PosRelativeTo")));
final EnumModel<AxialMethod> methodModel = new EnumModel<AxialMethod>(component, "AxialMethod", AxialMethod.axialOffsetMethods );
JComboBox<AxialMethod> relToCombo = new JComboBox<AxialMethod>( methodModel );
panel.add( relToCombo, "spanx, growx, wrap");
}
{ //// plus
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.Plus")), "right");
DoubleModel offsetModel = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
@ -96,17 +119,13 @@ public class RailButtonConfig extends RocketComponentConfig {
panel.add(offsetSpinner, "growx");
panel.add(new UnitSelector(offsetModel), "growx");
panel.add(new BasicSlider(offsetModel.getSliderModel(
new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE),
new DoubleModel(component.getParent(), "Length"))),
new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE),
new DoubleModel(component.getParent(), "Length"))),
"w 100lp, wrap para");
}
primary.add(panel, "grow, gapright 201p");
panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
}
//// Instance count
panel.add( instanceablePanel(rbc), "span, wrap");
panel.add(instanceablePanel(rbc), "span, wrap");
//// Material
panel.add(materialPanel(Material.Type.BULK),"span, wrap");

View File

@ -25,6 +25,7 @@ import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.database.ComponentPresetDatabase;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.BooleanModel;
@ -37,6 +38,7 @@ import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.StyledLabel.Style;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.dialogs.preset.ComponentPresetChooserDialog;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.widgets.SelectColorButton;
import net.sf.openrocket.l10n.Translator;
@ -117,8 +119,20 @@ public class RocketComponentConfig extends JPanel {
// If the component supports a preset, show the preset selection box.
presetModel = new PresetModel(this, document, component);
presetComboBox = new JComboBox(presetModel);
presetComboBox.setMaximumRowCount(25);
presetComboBox.setEditable(false);
this.add(presetComboBox, "");
presetComboBox.setToolTipText(trans.get("PresetModel.combo.ttip"));
this.add(presetComboBox, "growx 110");
final JButton selectPreset = new SelectColorButton(trans.get("PresetModel.lbl.partsLib"));
selectPreset.setToolTipText(trans.get("PresetModel.lbl.partsLib.ttip"));
selectPreset.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectPreset();
}
});
this.add(selectPreset);
}
tabbedPane = new JTabbedPane();
@ -243,6 +257,21 @@ public class RocketComponentConfig extends JPanel {
}
}
private void selectPreset() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (presetComboBox == null || presetModel == null) return;
((ComponentPresetDatabase) Application.getComponentPresetDao()).addDatabaseListener(presetModel);
ComponentPresetChooserDialog dialog =
new ComponentPresetChooserDialog(SwingUtilities.getWindowAncestor(RocketComponentConfig.this),
component, presetModel);
dialog.setVisible(true);
((ComponentPresetDatabase) Application.getComponentPresetDao()).removeChangeListener(presetModel);
}
});
}
public void clearConfigListeners() {
if (appearancePanel != null) {
appearancePanel.clearConfigListeners();
@ -353,7 +382,7 @@ public class RocketComponentConfig extends JPanel {
}
protected JPanel instanceablePanel( Instanceable inst ){
JPanel panel = new JPanel( new MigLayout("fill"));
JPanel panel = new JPanel( new MigLayout("fill, insets 0") );
{ // Instance Count
panel.add(new JLabel(trans.get("RocketCompCfg.lbl.InstanceCount")));
IntegerModel countModel = new IntegerModel(component, "InstanceCount", 1);
@ -369,7 +398,11 @@ public class RocketComponentConfig extends JPanel {
separationSpinner.setEditor(new SpinnerEditor(separationSpinner));
panel.add(separationSpinner, "growx");
panel.add(new UnitSelector(separationModel), "growx");
panel.add(new BasicSlider(separationModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap para");
double maxSeparationDistance = 0.1;
if (component.getParent() != null && component.getParent().getLength() > 0) {
maxSeparationDistance = component.getParent().getLength();
}
panel.add(new BasicSlider(separationModel.getSliderModel(0, 0.001, maxSeparationDistance)), "w 100lp, wrap para");
}
return panel;
}

View File

@ -346,7 +346,7 @@ public class ScaleDialog extends JDialog {
panel.add(selectionOption, "growx, wrap para*2");
// Select the 'scale component / scale selection and all subcomponents' if a component is selected
if (selection != null && selection.size() > 0) {
if (options.size() > 1 && selection != null && selection.size() > 0) {
boolean entireRocket = false; // Flag to scale entire rocket
for (RocketComponent component : selection) {
if (component instanceof Rocket || (component instanceof AxialStage && !(component instanceof ParallelStage))) {

View File

@ -91,7 +91,7 @@ public class MotorChooserDialog extends JDialog implements CloseableDialog {
// Set the closeable dialog after all initialization
selectionPanel.setCloseableDialog(this);
GUIUtil.setDisposableDialogOptions(this, cancelButton);
GUIUtil.setWindowIcons(this);
}
public void setMotorMountAndConfig( FlightConfigurationId _fcid, MotorMount _mount ) {

View File

@ -11,6 +11,7 @@ import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.main.BasicFrame;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.unit.UnitGroup;
@ -93,7 +94,6 @@ public class DesignPreferencesPanel extends PreferencesPanel {
// // Always open leftmost tab when opening a component edit dialog
final JCheckBox alwaysOpenLeftmostTab = new JCheckBox(
trans.get("pref.dlg.checkbox.AlwaysOpenLeftmost"));
alwaysOpenLeftmostTab.setSelected(preferences.isAlwaysOpenLeftmostTab());
alwaysOpenLeftmostTab.setToolTipText(trans.get("pref.dlg.checkbox.AlwaysOpenLeftmost.ttip"));
alwaysOpenLeftmostTab.addActionListener(new ActionListener() {
@ -103,7 +103,7 @@ public class DesignPreferencesPanel extends PreferencesPanel {
.isSelected());
}
});
this.add(alwaysOpenLeftmostTab, "wrap, growx, span 2");
this.add(alwaysOpenLeftmostTab, "wrap, growx, spanx");
// // Update flight estimates in the design window
final JCheckBox updateEstimates = new JCheckBox(
@ -117,5 +117,23 @@ public class DesignPreferencesPanel extends PreferencesPanel {
}
});
this.add(updateEstimates, "wrap, growx, sg combos ");
// // Only show pod set/booster markers when they are selected
final JCheckBox showMarkers = new JCheckBox(
trans.get("pref.dlg.checkbox.Markers"));
showMarkers.setToolTipText(trans.get("pref.dlg.checkbox.Markers.ttip"));
showMarkers.setSelected(preferences.isShowMarkers());
showMarkers.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences.setShowMarkers(showMarkers
.isSelected());
// Update all BasicFrame rocket panel figures because it can change due to the preference change
for (BasicFrame frame : BasicFrame.getAllFrames()) {
frame.getRocketPanel().updateFigures();
}
}
});
this.add(showMarkers, "wrap, growx, spanx");
}
}

Some files were not shown because too many files have changed in this diff Show More