Refactor tube exporter to use cylinder exporter
This commit is contained in:
parent
87c4cbec97
commit
7ebed840b6
@ -29,20 +29,10 @@ public class BodyTubeExporter extends RocketComponentExporter<BodyTube> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateMesh(float outerRadius, float innerRadius, float length, boolean isFilled,
|
private void generateMesh(float outerRadius, float innerRadius, float length, boolean isFilled, InstanceContext context) {
|
||||||
InstanceContext context) {
|
// Generate the mesh
|
||||||
int startIdx = obj.getNumVertices();
|
int startIdx = obj.getNumVertices();
|
||||||
|
TubeExporter.addTubeMesh(obj, transformer, groupName, outerRadius, isFilled ? 0 : innerRadius, length, LOD);
|
||||||
if (isFilled || Float.compare(innerRadius, 0) == 0) {
|
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, groupName, outerRadius, length, true, LOD);
|
|
||||||
} else {
|
|
||||||
if (Float.compare(innerRadius, outerRadius) == 0) {
|
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, groupName, outerRadius, length, false, LOD);
|
|
||||||
} else {
|
|
||||||
TubeExporter.addTubeMesh(obj, transformer, groupName, outerRadius, innerRadius, length, LOD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
|
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
|
||||||
|
|
||||||
// Translate the mesh to the position in the rocket
|
// Translate the mesh to the position in the rocket
|
||||||
|
@ -30,19 +30,9 @@ public class LaunchLugExporter extends RocketComponentExporter<LaunchLug> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateMesh(float outerRadius, float innerRadius, float length, InstanceContext context) {
|
private void generateMesh(float outerRadius, float innerRadius, float length, InstanceContext context) {
|
||||||
|
// Generate the mesh
|
||||||
int startIdx = obj.getNumVertices();
|
int startIdx = obj.getNumVertices();
|
||||||
|
|
||||||
// Generate the instance mesh
|
|
||||||
if (Float.compare(innerRadius, 0) == 0) {
|
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, groupName, outerRadius, length, true, LOD);
|
|
||||||
} else {
|
|
||||||
if (Float.compare(innerRadius, outerRadius) == 0) {
|
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, groupName, outerRadius, length, false, LOD);
|
|
||||||
} else {
|
|
||||||
TubeExporter.addTubeMesh(obj, transformer, groupName, outerRadius, innerRadius, length, LOD);
|
TubeExporter.addTubeMesh(obj, transformer, groupName, outerRadius, innerRadius, length, LOD);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
|
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
|
||||||
|
|
||||||
// Translate the mesh to the position in the rocket
|
// Translate the mesh to the position in the rocket
|
||||||
|
@ -53,45 +53,45 @@ public class RailButtonExporter extends RocketComponentExporter<RailButton> {
|
|||||||
final int normalStartIdx = obj.getNumNormals();
|
final int normalStartIdx = obj.getNumNormals();
|
||||||
|
|
||||||
// Generate base cylinder
|
// Generate base cylinder
|
||||||
List<Integer> baseCylinderBottomVertices = new ArrayList<>();
|
List<Integer> baseCylinderForeVertices = new ArrayList<>();
|
||||||
List<Integer> baseCylinderTopVertices = new ArrayList<>();
|
List<Integer> baseCylinderAftVertices = new ArrayList<>();
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, null, outerRadius, baseHeight, false, LOD,
|
CylinderExporter.addCylinderMesh(obj, transformer, null, outerRadius, baseHeight, false, LOD,
|
||||||
baseCylinderBottomVertices, baseCylinderTopVertices);
|
baseCylinderForeVertices, baseCylinderAftVertices);
|
||||||
|
|
||||||
// Generate inner cylinder
|
// Generate inner cylinder
|
||||||
int tmpStartIdx = obj.getNumVertices();
|
int tmpStartIdx = obj.getNumVertices();
|
||||||
List<Integer> innerCylinderBottomVertices = new ArrayList<>();
|
List<Integer> innerCylinderForeVertices = new ArrayList<>();
|
||||||
List<Integer> innerCylinderTopVertices = new ArrayList<>();
|
List<Integer> innerCylinderAftVertices = new ArrayList<>();
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, null, innerRadius, innerHeight, false, LOD,
|
CylinderExporter.addCylinderMesh(obj, transformer, null, innerRadius, innerHeight, false, LOD,
|
||||||
innerCylinderBottomVertices, innerCylinderTopVertices);
|
innerCylinderForeVertices, innerCylinderAftVertices);
|
||||||
int tmpEndIdx = Math.max(obj.getNumVertices() - 1, tmpStartIdx);
|
int tmpEndIdx = Math.max(obj.getNumVertices() - 1, tmpStartIdx);
|
||||||
FloatTuple locOffs = transformer.convertLocWithoutOriginOffs(baseHeight, 0, 0);
|
FloatTuple locOffs = transformer.convertLocWithoutOriginOffs(baseHeight, 0, 0);
|
||||||
ObjUtils.translateVertices(obj, tmpStartIdx, tmpEndIdx, locOffs.getX(), locOffs.getY(), locOffs.getZ());
|
ObjUtils.translateVertices(obj, tmpStartIdx, tmpEndIdx, locOffs.getX(), locOffs.getY(), locOffs.getZ());
|
||||||
|
|
||||||
// Generate flange cylinder
|
// Generate flange cylinder
|
||||||
tmpStartIdx = obj.getNumVertices();
|
tmpStartIdx = obj.getNumVertices();
|
||||||
List<Integer> flangeCylinderBottomVertices = new ArrayList<>();
|
List<Integer> flangeCylinderForeVertices = new ArrayList<>();
|
||||||
List<Integer> flangeCylinderTopVertices = new ArrayList<>();
|
List<Integer> flangeCylinderAftVertices = new ArrayList<>();
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, null, outerRadius, flangeHeight, false, LOD,
|
CylinderExporter.addCylinderMesh(obj, transformer, null, outerRadius, flangeHeight, false, LOD,
|
||||||
flangeCylinderBottomVertices, flangeCylinderTopVertices);
|
flangeCylinderForeVertices, flangeCylinderAftVertices);
|
||||||
tmpEndIdx = Math.max(obj.getNumVertices() - 1, tmpStartIdx);
|
tmpEndIdx = Math.max(obj.getNumVertices() - 1, tmpStartIdx);
|
||||||
locOffs = transformer.convertLocWithoutOriginOffs(baseHeight + innerHeight, 0, 0);
|
locOffs = transformer.convertLocWithoutOriginOffs(baseHeight + innerHeight, 0, 0);
|
||||||
ObjUtils.translateVertices(obj, tmpStartIdx, tmpEndIdx, locOffs.getX(), locOffs.getY(), locOffs.getZ());
|
ObjUtils.translateVertices(obj, tmpStartIdx, tmpEndIdx, locOffs.getX(), locOffs.getY(), locOffs.getZ());
|
||||||
|
|
||||||
// Generate base disk
|
// Generate base disk
|
||||||
DiskExporter.closeDiskMesh(obj, transformer, null, baseCylinderTopVertices, false, true);
|
DiskExporter.closeDiskMesh(obj, transformer, null, baseCylinderForeVertices, false, true);
|
||||||
|
|
||||||
// Generate base inner disk
|
// Generate base inner disk
|
||||||
DiskExporter.closeDiskMesh(obj, transformer, null, baseCylinderBottomVertices, innerCylinderTopVertices, false, false);
|
DiskExporter.closeDiskMesh(obj, transformer, null, baseCylinderAftVertices, innerCylinderForeVertices, false, false);
|
||||||
|
|
||||||
// Generate flange inner disk
|
// Generate flange inner disk
|
||||||
DiskExporter.closeDiskMesh(obj, transformer, null, innerCylinderBottomVertices, flangeCylinderTopVertices, true, true);
|
DiskExporter.closeDiskMesh(obj, transformer, null, innerCylinderAftVertices, flangeCylinderForeVertices, true, true);
|
||||||
|
|
||||||
// Generate flange disk/screw
|
// Generate flange disk/screw
|
||||||
if (Float.compare(screwHeight, 0) == 0) {
|
if (Float.compare(screwHeight, 0) == 0) {
|
||||||
DiskExporter.closeDiskMesh(obj, transformer, null, flangeCylinderBottomVertices, false, false);
|
DiskExporter.closeDiskMesh(obj, transformer, null, flangeCylinderAftVertices, false, false);
|
||||||
} else {
|
} else {
|
||||||
addScrew(obj, baseHeight, innerHeight, flangeHeight, outerRadius, screwHeight, LOD, flangeCylinderBottomVertices);
|
addScrew(obj, baseHeight, innerHeight, flangeHeight, outerRadius, screwHeight, LOD, flangeCylinderAftVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,18 +30,9 @@ public class RingComponentExporter extends RocketComponentExporter<RingComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateMesh(float outerRadius, float innerRadius, float length, InstanceContext context) {
|
private void generateMesh(float outerRadius, float innerRadius, float length, InstanceContext context) {
|
||||||
|
// Generate the mesh
|
||||||
int startIdx = obj.getNumVertices();
|
int startIdx = obj.getNumVertices();
|
||||||
|
|
||||||
if (Float.compare(innerRadius, 0) == 0) {
|
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, groupName, outerRadius, length, true, LOD);
|
|
||||||
} else {
|
|
||||||
if (Float.compare(innerRadius, outerRadius) == 0) {
|
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, groupName, outerRadius, length, false, LOD);
|
|
||||||
} else {
|
|
||||||
TubeExporter.addTubeMesh(obj, transformer, groupName, outerRadius, innerRadius, length, LOD);
|
TubeExporter.addTubeMesh(obj, transformer, groupName, outerRadius, innerRadius, length, LOD);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
|
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
|
||||||
|
|
||||||
// Translate the mesh to the position in the rocket
|
// Translate the mesh to the position in the rocket
|
||||||
|
@ -64,9 +64,9 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
|
|||||||
float outerFore = (float) component.getForeRadius();
|
float outerFore = (float) component.getForeRadius();
|
||||||
float innerFore = (float) (component.getForeRadius() - component.getThickness());
|
float innerFore = (float) (component.getForeRadius() - component.getThickness());
|
||||||
|
|
||||||
TubeExporter.addTubeMesh(obj, transformer, null, outerAft, outerFore, innerAft, innerFore,
|
TubeExporter.addTubeMesh(obj, transformer, null, outerFore, outerAft, innerFore, innerAft,
|
||||||
(float) component.getLength(), this.nrOfSides,
|
(float) component.getLength(), this.nrOfSides,
|
||||||
outsideAftRingVertices, outsideForeRingVertices, insideAftRingVertices, insideForeRingVertices);
|
outsideForeRingVertices, outsideAftRingVertices, insideForeRingVertices, insideAftRingVertices);
|
||||||
}
|
}
|
||||||
// Otherwise, use complex geometry
|
// Otherwise, use complex geometry
|
||||||
else {
|
else {
|
||||||
@ -370,10 +370,10 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
|
|||||||
private void addShoulder(float shoulderRadius, float shoulderLength, float shoulderThickness, boolean isCapped,
|
private void addShoulder(float shoulderRadius, float shoulderLength, float shoulderThickness, boolean isCapped,
|
||||||
boolean isForeSide, int nrOfSides, List<Integer> outerRingVertices, List<Integer> innerRingVertices) {
|
boolean isForeSide, int nrOfSides, List<Integer> outerRingVertices, List<Integer> innerRingVertices) {
|
||||||
final float innerCylinderRadius = isCapped ? 0 : shoulderRadius - shoulderThickness;
|
final float innerCylinderRadius = isCapped ? 0 : shoulderRadius - shoulderThickness;
|
||||||
final List<Integer> outerCylinderBottomVertices = new ArrayList<>();
|
final List<Integer> outerCylinderForeVertices = new ArrayList<>();
|
||||||
final List<Integer> outerCylinderTopVertices = new ArrayList<>();
|
final List<Integer> outerCylinderAftVertices = new ArrayList<>();
|
||||||
final List<Integer> innerCylinderBottomVertices = isCapped ? null : new ArrayList<>();
|
final List<Integer> innerCylinderForeVertices = isCapped ? null : new ArrayList<>();
|
||||||
final List<Integer> innerCylinderTopVertices = isCapped ? null : new ArrayList<>();
|
final List<Integer> innerCylinderAftVertices = isCapped ? null : new ArrayList<>();
|
||||||
int startIdx;
|
int startIdx;
|
||||||
int endIdx;
|
int endIdx;
|
||||||
|
|
||||||
@ -403,7 +403,7 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
|
|||||||
// Generate outer cylinder (no. 3)
|
// Generate outer cylinder (no. 3)
|
||||||
startIdx = obj.getNumVertices();
|
startIdx = obj.getNumVertices();
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, null, shoulderRadius, shoulderLength,
|
CylinderExporter.addCylinderMesh(obj, transformer, null, shoulderRadius, shoulderLength,
|
||||||
false, nrOfSides, outerCylinderBottomVertices, outerCylinderTopVertices);
|
false, nrOfSides, outerCylinderForeVertices, outerCylinderAftVertices);
|
||||||
endIdx = Math.max(obj.getNumVertices() - 1, startIdx);
|
endIdx = Math.max(obj.getNumVertices() - 1, startIdx);
|
||||||
|
|
||||||
// Translate the outer cylinder to the correct position
|
// Translate the outer cylinder to the correct position
|
||||||
@ -415,7 +415,7 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
|
|||||||
if (!isCapped) {
|
if (!isCapped) {
|
||||||
startIdx = obj.getNumVertices();
|
startIdx = obj.getNumVertices();
|
||||||
CylinderExporter.addCylinderMesh(obj, transformer, null, innerCylinderRadius, shoulderLength + shoulderThickness,
|
CylinderExporter.addCylinderMesh(obj, transformer, null, innerCylinderRadius, shoulderLength + shoulderThickness,
|
||||||
false, false, nrOfSides, innerCylinderBottomVertices, innerCylinderTopVertices);
|
false, false, nrOfSides, innerCylinderForeVertices, innerCylinderAftVertices);
|
||||||
endIdx = Math.max(obj.getNumVertices() - 1, startIdx);
|
endIdx = Math.max(obj.getNumVertices() - 1, startIdx);
|
||||||
|
|
||||||
// Translate the outer cylinder to the correct position
|
// Translate the outer cylinder to the correct position
|
||||||
@ -426,23 +426,23 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
|
|||||||
|
|
||||||
// Generate shoulder top disk (no. 4)
|
// Generate shoulder top disk (no. 4)
|
||||||
if (isForeSide) {
|
if (isForeSide) {
|
||||||
DiskExporter.closeDiskMesh(obj, transformer, null, outerCylinderTopVertices, innerCylinderTopVertices, false, true);
|
DiskExporter.closeDiskMesh(obj, transformer, null, outerCylinderForeVertices, innerCylinderForeVertices, false, true);
|
||||||
} else {
|
} else {
|
||||||
DiskExporter.closeDiskMesh(obj, transformer, null, outerCylinderBottomVertices, innerCylinderBottomVertices, false, false);
|
DiskExporter.closeDiskMesh(obj, transformer, null, outerCylinderAftVertices, innerCylinderAftVertices, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate transition outer disk (no. 5)
|
// Generate transition outer disk (no. 5)
|
||||||
if (isForeSide) {
|
if (isForeSide) {
|
||||||
DiskExporter.closeDiskMesh(obj, transformer, null, outerRingVertices, outerCylinderBottomVertices, false, true);
|
DiskExporter.closeDiskMesh(obj, transformer, null, outerRingVertices, outerCylinderAftVertices, false, true);
|
||||||
} else {
|
} else {
|
||||||
DiskExporter.closeDiskMesh(obj, transformer, null, outerRingVertices, outerCylinderTopVertices, false, false);
|
DiskExporter.closeDiskMesh(obj, transformer, null, outerRingVertices, outerCylinderForeVertices, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate transition inner disk (no. 6)
|
// Generate transition inner disk (no. 6)
|
||||||
if (isForeSide) {
|
if (isForeSide) {
|
||||||
DiskExporter.closeDiskMesh(obj, transformer, null, innerRingVertices, innerCylinderBottomVertices, false, false);
|
DiskExporter.closeDiskMesh(obj, transformer, null, innerRingVertices, innerCylinderAftVertices, false, false);
|
||||||
} else {
|
} else {
|
||||||
DiskExporter.closeDiskMesh(obj, transformer, null, innerRingVertices, innerCylinderTopVertices, false, true);
|
DiskExporter.closeDiskMesh(obj, transformer, null, innerRingVertices, innerCylinderForeVertices, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,19 +14,20 @@ public class CylinderExporter {
|
|||||||
* @param obj The obj to add the mesh to
|
* @param obj The obj to add the mesh to
|
||||||
* @param transformer The coordinate system transformer to use to switch from the OpenRocket coordinate system to a custom OBJ coordinate system
|
* @param transformer The coordinate system transformer to use to switch from the OpenRocket coordinate system to a custom OBJ coordinate system
|
||||||
* @param groupName The name of the group to add the mesh to, or null if no group should be added (use the active group)
|
* @param groupName The name of the group to add the mesh to, or null if no group should be added (use the active group)
|
||||||
* @param radius The radius of the cylinder
|
* @param foreRadius The fore (top) radius of the cylinder
|
||||||
|
* @param aftRadius The aft (bottom) radius of the cylinder
|
||||||
* @param length The length of the cylinder
|
* @param length The length of the cylinder
|
||||||
* @param numSides The number of sides of the cylinder
|
* @param numSides The number of sides of the cylinder
|
||||||
* @param solid Whether the cylinder should be solid (true) or hollow (false)
|
* @param solid Whether the cylinder should be solid (true) or hollow (false)
|
||||||
* NOTE: Culling is not really thought of for the hollow cylinder; this mode is really meant to be
|
* NOTE: Culling is not really thought of for the hollow cylinder; this mode is really meant to be
|
||||||
* combined with other objects
|
* combined with other objects
|
||||||
* @param isOutside Whether the cylinder is an outside face (true) or inside face (false)
|
* @param isOutside Whether the cylinder is an outside face (true) or inside face (false)
|
||||||
* @param bottomRingVertices A list to add the bottom ring vertex indices to
|
* @param foreRingVertices A list to add the fore (top) ring vertex indices to
|
||||||
* @param topRingVertices A list to add the top ring vertex indices to
|
* @param aftRingVertices A list to add the aft (bottom) ring vertex indices to
|
||||||
*/
|
*/
|
||||||
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
||||||
float radius, float length, int numSides, boolean solid, boolean isOutside,
|
float foreRadius, float aftRadius, float length, int numSides, boolean solid, boolean isOutside,
|
||||||
List<Integer> bottomRingVertices, List<Integer> topRingVertices) {
|
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
|
||||||
// Set the new group
|
// Set the new group
|
||||||
if (groupName != null) {
|
if (groupName != null) {
|
||||||
obj.setActiveGroupNames(groupName);
|
obj.setActiveGroupNames(groupName);
|
||||||
@ -47,10 +48,10 @@ public class CylinderExporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate side top vertices
|
// Generate side top vertices
|
||||||
generateRingVertices(obj, transformer, startIdx, numSides, 0, radius, isOutside, topRingVertices);
|
generateRingVertices(obj, transformer, startIdx, numSides, 0, foreRadius, isOutside, foreRingVertices);
|
||||||
|
|
||||||
// Generate side bottom vertices
|
// Generate side bottom vertices
|
||||||
generateRingVertices(obj, transformer, startIdx + numSides, numSides, length, radius, isOutside, bottomRingVertices);
|
generateRingVertices(obj, transformer, startIdx + numSides, numSides, length, aftRadius, isOutside, aftRingVertices);
|
||||||
|
|
||||||
// Create faces for the bottom and top
|
// Create faces for the bottom and top
|
||||||
if (solid) {
|
if (solid) {
|
||||||
@ -111,28 +112,34 @@ public class CylinderExporter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
||||||
|
float radius, float length, int numSides, boolean solid, boolean isOutside,
|
||||||
|
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
|
||||||
|
addCylinderMesh(obj, transformer, groupName, radius, radius, length, numSides, solid, isOutside, foreRingVertices, aftRingVertices);
|
||||||
|
}
|
||||||
|
|
||||||
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
||||||
float radius, float height, int numSides, boolean solid,
|
float radius, float height, int numSides, boolean solid,
|
||||||
List<Integer> bottomRingVertices, List<Integer> topRingVertices) {
|
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
|
||||||
addCylinderMesh(obj, transformer, groupName, radius, height, numSides, solid, true, bottomRingVertices, topRingVertices);
|
addCylinderMesh(obj, transformer, groupName, radius, height, numSides, solid, true, foreRingVertices, aftRingVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
||||||
float radius, float height, boolean solid, ObjUtils.LevelOfDetail LOD,
|
float radius, float height, boolean solid, ObjUtils.LevelOfDetail LOD,
|
||||||
List<Integer> bottomRingVertices, List<Integer> topRingVertices) {
|
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
|
||||||
addCylinderMesh(obj, transformer, groupName, radius, height, LOD.getNrOfSides(radius), solid, bottomRingVertices, topRingVertices);
|
addCylinderMesh(obj, transformer, groupName, radius, height, LOD.getNrOfSides(radius), solid, foreRingVertices, aftRingVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
||||||
float radius, float height, boolean solid, boolean isOutside, int nrOfSlices,
|
float radius, float height, boolean solid, boolean isOutside, int nrOfSlices,
|
||||||
List<Integer> bottomRingVertices, List<Integer> topRingVertices) {
|
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
|
||||||
addCylinderMesh(obj, transformer, groupName, radius, height, nrOfSlices, solid, isOutside, bottomRingVertices, topRingVertices);
|
addCylinderMesh(obj, transformer, groupName, radius, height, nrOfSlices, solid, isOutside, foreRingVertices, aftRingVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
||||||
float radius, float height, boolean solid, int nrOfSlices,
|
float radius, float height, boolean solid, int nrOfSlices,
|
||||||
List<Integer> bottomRingVertices, List<Integer> topRingVertices) {
|
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
|
||||||
addCylinderMesh(obj, transformer, groupName, radius, height, nrOfSlices, solid, bottomRingVertices, topRingVertices);
|
addCylinderMesh(obj, transformer, groupName, radius, height, nrOfSlices, solid, foreRingVertices, aftRingVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
||||||
|
@ -6,6 +6,7 @@ import net.sf.openrocket.file.wavefrontobj.DefaultObj;
|
|||||||
import net.sf.openrocket.file.wavefrontobj.DefaultObjFace;
|
import net.sf.openrocket.file.wavefrontobj.DefaultObjFace;
|
||||||
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter.generateRingVertices;
|
import static net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter.generateRingVertices;
|
||||||
@ -16,23 +17,25 @@ public class TubeExporter {
|
|||||||
* It is drawn in the origin of the OBJ coordinate system. The longitudinal axis is positive, converted OpenRocket x-axis.
|
* It is drawn in the origin of the OBJ coordinate system. The longitudinal axis is positive, converted OpenRocket x-axis.
|
||||||
* @param obj The obj to add the mesh to
|
* @param obj The obj to add the mesh to
|
||||||
* @param groupName The name of the group to add the mesh to, or null if no group should be added (use the active group)
|
* @param groupName The name of the group to add the mesh to, or null if no group should be added (use the active group)
|
||||||
* @param aftOuterRadius The outer radius of the aft (bottom) of the tube
|
|
||||||
* @param foreOuterRadius The outer radius of the fore (top) of the tube
|
* @param foreOuterRadius The outer radius of the fore (top) of the tube
|
||||||
* @param aftInnerRadius The inner radius of the aft (bottom) of the tube
|
* @param aftOuterRadius The outer radius of the aft (bottom) of the tube
|
||||||
* @param foreInnerRadius The inner radius of the fore (top) of the tube
|
* @param foreInnerRadius The inner radius of the fore (top) of the tube
|
||||||
|
* Set to 0, together with aftInnerRadius, to create a solid tube
|
||||||
|
* @param aftInnerRadius The inner radius of the aft (bottom) of the tube
|
||||||
|
* Set to 0, together with foreInnerRadius, to create a solid tube
|
||||||
* @param length The length of the tube
|
* @param length The length of the tube
|
||||||
* @param numSides The number of sides of the tube
|
* @param numSides The number of sides of the tube
|
||||||
* @param bottomOuterVertices A list to add the indices of the bottom outer vertices to, or null if the indices are not needed
|
* @param foreOuterVertices A list to add the indices of the fore (top) outer vertices to, or null if the indices are not needed
|
||||||
* @param topOuterVertices A list to add the indices of the top outer vertices to, or null if the indices are not needed
|
* @param aftOuterVertices A list to add the indices of the aft (bottom) outer vertices to, or null if the indices are not needed
|
||||||
* @param bottomInnerVertices A list to add the indices of the bottom inner vertices to, or null if the indices are not needed
|
* @param foreInnerVertices A list to add the indices of the fore (top) inner vertices to, or null if the indices are not needed
|
||||||
* @param topInnerVertices A list to add the indices of the top inner vertices to, or null if the indices are not needed
|
* @param aftInnerVertices A list to add the indices of the aft (bottom) inner vertices to, or null if the indices are not needed
|
||||||
*/
|
*/
|
||||||
public static void addTubeMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
public static void addTubeMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
|
||||||
float aftOuterRadius, float foreOuterRadius,
|
float foreOuterRadius, float aftOuterRadius,
|
||||||
float aftInnerRadius, float foreInnerRadius, float length, int numSides,
|
float foreInnerRadius, float aftInnerRadius, float length, int numSides,
|
||||||
List<Integer> bottomOuterVertices, List<Integer> topOuterVertices,
|
List<Integer> foreOuterVertices, List<Integer> aftOuterVertices,
|
||||||
List<Integer> bottomInnerVertices, List<Integer> topInnerVertices) {
|
List<Integer> foreInnerVertices, List<Integer> aftInnerVertices) {
|
||||||
if (aftInnerRadius > aftOuterRadius || foreInnerRadius > foreOuterRadius) {
|
if (Float.compare(aftInnerRadius, aftOuterRadius) > 0 || Float.compare(foreInnerRadius, foreOuterRadius) > 0) {
|
||||||
throw new IllegalArgumentException("Inner radius must be less than outer radius");
|
throw new IllegalArgumentException("Inner radius must be less than outer radius");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,102 +44,38 @@ public class TubeExporter {
|
|||||||
obj.setActiveGroupNames(groupName);
|
obj.setActiveGroupNames(groupName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other meshes may have been added to the obj, so we need to keep track of the starting indices
|
// We need to store the vertices to create the closing disks, so we'll create lists if they do not exist
|
||||||
int startIdx = obj.getNumVertices();
|
if (foreOuterVertices == null) {
|
||||||
int normalsStartIdx = obj.getNumNormals();
|
foreOuterVertices = new ArrayList<>();
|
||||||
|
}
|
||||||
obj.addNormal(transformer.convertLocWithoutOriginOffs(-1, 0, 0)); // Top faces normal
|
if (aftOuterVertices == null) {
|
||||||
obj.addNormal(transformer.convertLocWithoutOriginOffs(1, 0, 0)); // Bottom faces normal
|
aftOuterVertices = new ArrayList<>();
|
||||||
|
}
|
||||||
// Generate top outside vertices
|
if (foreInnerVertices == null) {
|
||||||
generateRingVertices(obj, transformer, startIdx, numSides, 0, foreOuterRadius, true, topOuterVertices);
|
foreInnerVertices = new ArrayList<>();
|
||||||
|
}
|
||||||
// Generate top inside vertices
|
if (aftInnerVertices == null) {
|
||||||
generateRingVertices(obj, transformer, startIdx + numSides, numSides, 0, foreInnerRadius, false, topInnerVertices);
|
aftInnerVertices = new ArrayList<>();
|
||||||
|
|
||||||
// Generate bottom outside vertices
|
|
||||||
generateRingVertices(obj, transformer, startIdx + 2*numSides, numSides, length, aftOuterRadius, true, bottomOuterVertices);
|
|
||||||
|
|
||||||
// Generate bottom inside vertices
|
|
||||||
generateRingVertices(obj, transformer, startIdx + 3*numSides, numSides, length, aftInnerRadius, false, bottomInnerVertices);
|
|
||||||
|
|
||||||
// Create top faces
|
|
||||||
for (int i = 0; i < numSides; i++) {
|
|
||||||
int[] vertexIndices = new int[] {
|
|
||||||
i, // Bottom-left of quad outside vertex
|
|
||||||
((i + 1) % numSides), // Bottom-right of quad outside vertex
|
|
||||||
numSides + ((i + 1) % numSides), // Top-right of quad inside vertex
|
|
||||||
numSides + i, // Top-left of quad inside vertex
|
|
||||||
};
|
|
||||||
ObjUtils.offsetIndex(vertexIndices, startIdx);
|
|
||||||
int[] normalIndices = new int[] {0, 0, 0, 0};
|
|
||||||
ObjUtils.offsetIndex(normalIndices, normalsStartIdx);
|
|
||||||
|
|
||||||
DefaultObjFace face = new DefaultObjFace(vertexIndices, null, normalIndices);
|
|
||||||
obj.addFace(face);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create bottom faces
|
// Generate inside mesh
|
||||||
for (int i = 0; i < numSides; i++) {
|
boolean hasForeThickness = Float.compare(foreOuterRadius, foreInnerRadius) > 0 && Float.compare(foreInnerRadius, 0) > 0;
|
||||||
int[] vertexIndices = new int[] {
|
boolean hasAftThickness = Float.compare(aftOuterRadius, aftInnerRadius) > 0 && Float.compare(aftInnerRadius, 0) > 0;
|
||||||
2*numSides + i, // Bottom-left of quad outside vertex
|
if (hasForeThickness || hasAftThickness) {
|
||||||
3*numSides + i, // Top-left of quad inside vertex
|
CylinderExporter.addCylinderMesh(obj, transformer, null, foreInnerRadius, aftInnerRadius, length, numSides,
|
||||||
3*numSides + ((i + 1) % numSides), // Top-right of quad inside vertex
|
false, false, foreInnerVertices, aftInnerVertices);
|
||||||
2*numSides + ((i + 1) % numSides), // Bottom-right of quad outside vertex
|
|
||||||
};
|
|
||||||
ObjUtils.offsetIndex(vertexIndices, startIdx);
|
|
||||||
|
|
||||||
int[] normalIndices = new int[] {1, 1, 1, 1};
|
|
||||||
ObjUtils.offsetIndex(normalIndices, normalsStartIdx);
|
|
||||||
|
|
||||||
DefaultObjFace face = new DefaultObjFace(vertexIndices, null, normalIndices);
|
|
||||||
obj.addFace(face);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create outside side faces
|
// Generate outside mesh
|
||||||
for (int i = 0; i < numSides; i++) {
|
CylinderExporter.addCylinderMesh(obj, transformer, null, foreOuterRadius, aftOuterRadius, length, numSides,
|
||||||
final int nextIdx = (i + 1) % numSides;
|
!hasForeThickness && !hasAftThickness, true, foreOuterVertices, aftOuterVertices);
|
||||||
int[] vertexIndices = new int[]{
|
|
||||||
i, // Bottom-left of quad outside vertex
|
|
||||||
2*numSides + i, // Top-left of quad outside vertex
|
|
||||||
2*numSides + nextIdx, // Top-right of quad outside vertex
|
|
||||||
nextIdx, // Bottom-right of quad outside vertex
|
|
||||||
};
|
|
||||||
ObjUtils.offsetIndex(vertexIndices, startIdx);
|
|
||||||
|
|
||||||
int[] normalIndices = new int[]{
|
// Close the mesh
|
||||||
i, // Bottom-left of quad outside vertex
|
if (hasForeThickness) {
|
||||||
2*numSides + i, // Top-left of quad outside vertex
|
DiskExporter.closeDiskMesh(obj, transformer, null, foreOuterVertices, foreInnerVertices, false, true);
|
||||||
2*numSides + nextIdx, // Top-right of quad outside vertex
|
|
||||||
nextIdx, // Bottom-right of quad outside vertex
|
|
||||||
};
|
|
||||||
ObjUtils.offsetIndex(normalIndices, normalsStartIdx + 2); // Extra 2 offset for bottom and top normals
|
|
||||||
|
|
||||||
DefaultObjFace face = new DefaultObjFace(vertexIndices, null, normalIndices);
|
|
||||||
obj.addFace(face);
|
|
||||||
}
|
}
|
||||||
|
if (hasAftThickness) {
|
||||||
// Create inside side faces
|
DiskExporter.closeDiskMesh(obj, transformer, null, aftOuterVertices, aftInnerVertices, false, false);
|
||||||
for (int i = 0; i < numSides; i++) {
|
|
||||||
final int nextIdx = (i + 1) % numSides;
|
|
||||||
int[] vertexIndices = new int[]{
|
|
||||||
numSides + i, // Bottom-left of quad inside vertex
|
|
||||||
numSides + nextIdx, // Bottom-right of quad inside vertex
|
|
||||||
3*numSides + nextIdx, // Top-right of quad inside vertex
|
|
||||||
3*numSides + i, // Top-left of quad inside vertex
|
|
||||||
};
|
|
||||||
ObjUtils.offsetIndex(vertexIndices, startIdx);
|
|
||||||
|
|
||||||
int[] normalIndices = new int[]{
|
|
||||||
numSides + i, // Bottom-left of quad inside vertex
|
|
||||||
numSides + nextIdx, // Bottom-right of quad inside vertex
|
|
||||||
3*numSides + nextIdx, // Top-right of quad inside vertex
|
|
||||||
3*numSides + i, // Top-left of quad inside vertex
|
|
||||||
};
|
|
||||||
ObjUtils.offsetIndex(normalIndices, normalsStartIdx + 2); // Extra 2 offset for bottom and top normals
|
|
||||||
|
|
||||||
DefaultObjFace face = new DefaultObjFace(vertexIndices, null, normalIndices);
|
|
||||||
obj.addFace(face);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ import net.sf.openrocket.document.OpenRocketDocument;
|
|||||||
import net.sf.openrocket.document.OpenRocketDocumentFactory;
|
import net.sf.openrocket.document.OpenRocketDocumentFactory;
|
||||||
import net.sf.openrocket.file.GeneralRocketLoader;
|
import net.sf.openrocket.file.GeneralRocketLoader;
|
||||||
import net.sf.openrocket.file.RocketLoadException;
|
import net.sf.openrocket.file.RocketLoadException;
|
||||||
import net.sf.openrocket.file.openrocket.OpenRocketSaver;
|
|
||||||
import net.sf.openrocket.file.openrocket.OpenRocketSaverTest;
|
import net.sf.openrocket.file.openrocket.OpenRocketSaverTest;
|
||||||
import net.sf.openrocket.file.wavefrontobj.CoordTransform;
|
import net.sf.openrocket.file.wavefrontobj.CoordTransform;
|
||||||
import net.sf.openrocket.file.wavefrontobj.DefaultCoordTransform;
|
import net.sf.openrocket.file.wavefrontobj.DefaultCoordTransform;
|
||||||
@ -33,8 +32,6 @@ import net.sf.openrocket.rocketcomponent.Transition;
|
|||||||
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
|
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.TubeFinSet;
|
import net.sf.openrocket.rocketcomponent.TubeFinSet;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
|
||||||
import net.sf.openrocket.util.TestRockets;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -47,13 +44,8 @@ import java.util.List;
|
|||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
public class OBJExporterFactoryTest {
|
public class OBJExporterFactoryTest {
|
||||||
private final OpenRocketSaver saver = new OpenRocketSaver();
|
|
||||||
private static final File TMP_DIR = new File("./tmp/");
|
private static final File TMP_DIR = new File("./tmp/");
|
||||||
|
|
||||||
public static final String SIMULATION_EXTENSION_SCRIPT = "// Test < &\n// >\n// <![CDATA[";
|
|
||||||
|
|
||||||
private static Injector injector;
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setup() {
|
public static void setup() {
|
||||||
Module applicationModule = new ServicesForTesting();
|
Module applicationModule = new ServicesForTesting();
|
||||||
@ -68,7 +60,7 @@ public class OBJExporterFactoryTest {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
injector = Guice.createInjector(Modules.override(applicationModule).with(dbOverrides), pluginModule);
|
Injector injector = Guice.createInjector(Modules.override(applicationModule).with(dbOverrides), pluginModule);
|
||||||
Application.setInjector(injector);
|
Application.setInjector(injector);
|
||||||
|
|
||||||
if (!(TMP_DIR.exists() && TMP_DIR.isDirectory())) {
|
if (!(TMP_DIR.exists() && TMP_DIR.isDirectory())) {
|
||||||
@ -81,6 +73,7 @@ public class OBJExporterFactoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExport() throws IOException {
|
public void testExport() throws IOException {
|
||||||
|
// Rocket generation
|
||||||
Rocket rocket = OpenRocketDocumentFactory.createNewRocket().getRocket();
|
Rocket rocket = OpenRocketDocumentFactory.createNewRocket().getRocket();
|
||||||
AxialStage sustainer = rocket.getStage(0);
|
AxialStage sustainer = rocket.getStage(0);
|
||||||
|
|
||||||
@ -156,43 +149,35 @@ public class OBJExporterFactoryTest {
|
|||||||
InnerTube innerTube = new InnerTube();
|
InnerTube innerTube = new InnerTube();
|
||||||
bodyTube.addChild(innerTube);
|
bodyTube.addChild(innerTube);
|
||||||
|
|
||||||
rocket = loadRocket("/Users/SiboVanGool/Downloads/blbl.ork").getRocket(); // TODO: delete me
|
|
||||||
|
|
||||||
|
// ------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Create a list of components to export
|
||||||
List<RocketComponent> components = List.of(rocket);
|
List<RocketComponent> components = List.of(rocket);
|
||||||
|
|
||||||
|
// Create a temp file for storing the exported OBJ
|
||||||
Path tempFile = Files.createTempFile("testExport", ".obj");
|
Path tempFile = Files.createTempFile("testExport", ".obj");
|
||||||
String filePath = tempFile.toAbsolutePath().toString();
|
String filePath = tempFile.toAbsolutePath().toString();
|
||||||
filePath = "/Users/SiboVanGool/Downloads/testExport.obj"; // TODO: delete me
|
|
||||||
TestRockets.dumpRocket(rocket, "/Users/SiboVanGool/Downloads/test.ork"); // TODO: delete me
|
|
||||||
|
|
||||||
|
// Do the exporting
|
||||||
CoordTransform transformer = new DefaultCoordTransform(rocket.getLength());
|
CoordTransform transformer = new DefaultCoordTransform(rocket.getLength());
|
||||||
OBJExporterFactory exporterFactory = new OBJExporterFactory(components, rocket.getSelectedConfiguration(), true, false, true,
|
OBJExporterFactory exporterFactory = new OBJExporterFactory(components, rocket.getSelectedConfiguration(), true, false, true,
|
||||||
transformer, filePath);
|
transformer, filePath);
|
||||||
exporterFactory.doExport();
|
exporterFactory.doExport();
|
||||||
|
|
||||||
// Test with other parameters
|
|
||||||
/*noseCone.setShoulderCapped(false);
|
|
||||||
railButton.setScrewHeight(0);
|
|
||||||
|
|
||||||
|
// Test with other parameters
|
||||||
|
noseCone.setShoulderCapped(false);
|
||||||
|
railButton.setScrewHeight(0);
|
||||||
|
bodyTube.setFilled(true);
|
||||||
|
|
||||||
transformer = new DefaultCoordTransform(rocket.getLength());
|
transformer = new DefaultCoordTransform(rocket.getLength());
|
||||||
exporterFactory = new OBJExporterFactory(components, false, false, true,
|
exporterFactory = new OBJExporterFactory(components, rocket.getSelectedConfiguration(), false, false, true,
|
||||||
transformer, filePath);
|
transformer, filePath);
|
||||||
exporterFactory.doExport();*/
|
exporterFactory.doExport();
|
||||||
|
|
||||||
|
|
||||||
|
// Clean up
|
||||||
Files.delete(tempFile);
|
Files.delete(tempFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OpenRocketDocument loadRocket(String fileName) {
|
|
||||||
GeneralRocketLoader loader = new GeneralRocketLoader(new File(fileName));
|
|
||||||
OpenRocketDocument rocketDoc = null;
|
|
||||||
try {
|
|
||||||
rocketDoc = loader.load();
|
|
||||||
} catch (RocketLoadException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
fail("RocketLoadException while loading file " + fileName + " : " + e.getMessage());
|
|
||||||
}
|
|
||||||
return rocketDoc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user