Refactor tube exporter to use cylinder exporter

This commit is contained in:
SiboVG 2023-08-14 02:20:16 +02:00
parent 87c4cbec97
commit 7ebed840b6
8 changed files with 113 additions and 211 deletions

View File

@ -29,20 +29,10 @@ public class BodyTubeExporter extends RocketComponentExporter<BodyTube> {
}
}
private void generateMesh(float outerRadius, float innerRadius, float length, boolean isFilled,
InstanceContext context) {
private void generateMesh(float outerRadius, float innerRadius, float length, boolean isFilled, InstanceContext context) {
// Generate the mesh
int startIdx = obj.getNumVertices();
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);
}
}
TubeExporter.addTubeMesh(obj, transformer, groupName, outerRadius, isFilled ? 0 : innerRadius, length, LOD);
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
// Translate the mesh to the position in the rocket

View File

@ -30,19 +30,9 @@ public class LaunchLugExporter extends RocketComponentExporter<LaunchLug> {
}
private void generateMesh(float outerRadius, float innerRadius, float length, InstanceContext context) {
// Generate the mesh
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
// Translate the mesh to the position in the rocket

View File

@ -53,45 +53,45 @@ public class RailButtonExporter extends RocketComponentExporter<RailButton> {
final int normalStartIdx = obj.getNumNormals();
// Generate base cylinder
List<Integer> baseCylinderBottomVertices = new ArrayList<>();
List<Integer> baseCylinderTopVertices = new ArrayList<>();
List<Integer> baseCylinderForeVertices = new ArrayList<>();
List<Integer> baseCylinderAftVertices = new ArrayList<>();
CylinderExporter.addCylinderMesh(obj, transformer, null, outerRadius, baseHeight, false, LOD,
baseCylinderBottomVertices, baseCylinderTopVertices);
baseCylinderForeVertices, baseCylinderAftVertices);
// Generate inner cylinder
int tmpStartIdx = obj.getNumVertices();
List<Integer> innerCylinderBottomVertices = new ArrayList<>();
List<Integer> innerCylinderTopVertices = new ArrayList<>();
List<Integer> innerCylinderForeVertices = new ArrayList<>();
List<Integer> innerCylinderAftVertices = new ArrayList<>();
CylinderExporter.addCylinderMesh(obj, transformer, null, innerRadius, innerHeight, false, LOD,
innerCylinderBottomVertices, innerCylinderTopVertices);
innerCylinderForeVertices, innerCylinderAftVertices);
int tmpEndIdx = Math.max(obj.getNumVertices() - 1, tmpStartIdx);
FloatTuple locOffs = transformer.convertLocWithoutOriginOffs(baseHeight, 0, 0);
ObjUtils.translateVertices(obj, tmpStartIdx, tmpEndIdx, locOffs.getX(), locOffs.getY(), locOffs.getZ());
// Generate flange cylinder
tmpStartIdx = obj.getNumVertices();
List<Integer> flangeCylinderBottomVertices = new ArrayList<>();
List<Integer> flangeCylinderTopVertices = new ArrayList<>();
List<Integer> flangeCylinderForeVertices = new ArrayList<>();
List<Integer> flangeCylinderAftVertices = new ArrayList<>();
CylinderExporter.addCylinderMesh(obj, transformer, null, outerRadius, flangeHeight, false, LOD,
flangeCylinderBottomVertices, flangeCylinderTopVertices);
flangeCylinderForeVertices, flangeCylinderAftVertices);
tmpEndIdx = Math.max(obj.getNumVertices() - 1, tmpStartIdx);
locOffs = transformer.convertLocWithoutOriginOffs(baseHeight + innerHeight, 0, 0);
ObjUtils.translateVertices(obj, tmpStartIdx, tmpEndIdx, locOffs.getX(), locOffs.getY(), locOffs.getZ());
// Generate base disk
DiskExporter.closeDiskMesh(obj, transformer, null, baseCylinderTopVertices, false, true);
DiskExporter.closeDiskMesh(obj, transformer, null, baseCylinderForeVertices, false, true);
// 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
DiskExporter.closeDiskMesh(obj, transformer, null, innerCylinderBottomVertices, flangeCylinderTopVertices, true, true);
DiskExporter.closeDiskMesh(obj, transformer, null, innerCylinderAftVertices, flangeCylinderForeVertices, true, true);
// Generate flange disk/screw
if (Float.compare(screwHeight, 0) == 0) {
DiskExporter.closeDiskMesh(obj, transformer, null, flangeCylinderBottomVertices, false, false);
DiskExporter.closeDiskMesh(obj, transformer, null, flangeCylinderAftVertices, false, false);
} else {
addScrew(obj, baseHeight, innerHeight, flangeHeight, outerRadius, screwHeight, LOD, flangeCylinderBottomVertices);
addScrew(obj, baseHeight, innerHeight, flangeHeight, outerRadius, screwHeight, LOD, flangeCylinderAftVertices);
}

View File

@ -30,18 +30,9 @@ public class RingComponentExporter extends RocketComponentExporter<RingComponent
}
private void generateMesh(float outerRadius, float innerRadius, float length, InstanceContext context) {
// Generate the mesh
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
// Translate the mesh to the position in the rocket

View File

@ -64,9 +64,9 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
float outerFore = (float) component.getForeRadius();
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,
outsideAftRingVertices, outsideForeRingVertices, insideAftRingVertices, insideForeRingVertices);
outsideForeRingVertices, outsideAftRingVertices, insideForeRingVertices, insideAftRingVertices);
}
// Otherwise, use complex geometry
else {
@ -370,10 +370,10 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
private void addShoulder(float shoulderRadius, float shoulderLength, float shoulderThickness, boolean isCapped,
boolean isForeSide, int nrOfSides, List<Integer> outerRingVertices, List<Integer> innerRingVertices) {
final float innerCylinderRadius = isCapped ? 0 : shoulderRadius - shoulderThickness;
final List<Integer> outerCylinderBottomVertices = new ArrayList<>();
final List<Integer> outerCylinderTopVertices = new ArrayList<>();
final List<Integer> innerCylinderBottomVertices = isCapped ? null : new ArrayList<>();
final List<Integer> innerCylinderTopVertices = isCapped ? null : new ArrayList<>();
final List<Integer> outerCylinderForeVertices = new ArrayList<>();
final List<Integer> outerCylinderAftVertices = new ArrayList<>();
final List<Integer> innerCylinderForeVertices = isCapped ? null : new ArrayList<>();
final List<Integer> innerCylinderAftVertices = isCapped ? null : new ArrayList<>();
int startIdx;
int endIdx;
@ -403,7 +403,7 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
// Generate outer cylinder (no. 3)
startIdx = obj.getNumVertices();
CylinderExporter.addCylinderMesh(obj, transformer, null, shoulderRadius, shoulderLength,
false, nrOfSides, outerCylinderBottomVertices, outerCylinderTopVertices);
false, nrOfSides, outerCylinderForeVertices, outerCylinderAftVertices);
endIdx = Math.max(obj.getNumVertices() - 1, startIdx);
// Translate the outer cylinder to the correct position
@ -415,7 +415,7 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
if (!isCapped) {
startIdx = obj.getNumVertices();
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);
// Translate the outer cylinder to the correct position
@ -426,23 +426,23 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
// Generate shoulder top disk (no. 4)
if (isForeSide) {
DiskExporter.closeDiskMesh(obj, transformer, null, outerCylinderTopVertices, innerCylinderTopVertices, false, true);
DiskExporter.closeDiskMesh(obj, transformer, null, outerCylinderForeVertices, innerCylinderForeVertices, false, true);
} 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)
if (isForeSide) {
DiskExporter.closeDiskMesh(obj, transformer, null, outerRingVertices, outerCylinderBottomVertices, false, true);
DiskExporter.closeDiskMesh(obj, transformer, null, outerRingVertices, outerCylinderAftVertices, false, true);
} 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)
if (isForeSide) {
DiskExporter.closeDiskMesh(obj, transformer, null, innerRingVertices, innerCylinderBottomVertices, false, false);
DiskExporter.closeDiskMesh(obj, transformer, null, innerRingVertices, innerCylinderAftVertices, false, false);
} else {
DiskExporter.closeDiskMesh(obj, transformer, null, innerRingVertices, innerCylinderTopVertices, false, true);
DiskExporter.closeDiskMesh(obj, transformer, null, innerRingVertices, innerCylinderForeVertices, false, true);
}
}

View File

@ -14,19 +14,20 @@ public class CylinderExporter {
* @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 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 numSides The number of sides of the cylinder
* @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
* combined with other objects
* @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 topRingVertices A list to add the top ring vertex indices to
* @param foreRingVertices A list to add the fore (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,
float radius, float length, int numSides, boolean solid, boolean isOutside,
List<Integer> bottomRingVertices, List<Integer> topRingVertices) {
float foreRadius, float aftRadius, float length, int numSides, boolean solid, boolean isOutside,
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
// Set the new group
if (groupName != null) {
obj.setActiveGroupNames(groupName);
@ -47,10 +48,10 @@ public class CylinderExporter {
}
// 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
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
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,
float radius, float height, int numSides, boolean solid,
List<Integer> bottomRingVertices, List<Integer> topRingVertices) {
addCylinderMesh(obj, transformer, groupName, radius, height, numSides, solid, true, bottomRingVertices, topRingVertices);
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
addCylinderMesh(obj, transformer, groupName, radius, height, numSides, solid, true, foreRingVertices, aftRingVertices);
}
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
float radius, float height, boolean solid, ObjUtils.LevelOfDetail LOD,
List<Integer> bottomRingVertices, List<Integer> topRingVertices) {
addCylinderMesh(obj, transformer, groupName, radius, height, LOD.getNrOfSides(radius), solid, bottomRingVertices, topRingVertices);
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
addCylinderMesh(obj, transformer, groupName, radius, height, LOD.getNrOfSides(radius), solid, foreRingVertices, aftRingVertices);
}
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
float radius, float height, boolean solid, boolean isOutside, int nrOfSlices,
List<Integer> bottomRingVertices, List<Integer> topRingVertices) {
addCylinderMesh(obj, transformer, groupName, radius, height, nrOfSlices, solid, isOutside, bottomRingVertices, topRingVertices);
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
addCylinderMesh(obj, transformer, groupName, radius, height, nrOfSlices, solid, isOutside, foreRingVertices, aftRingVertices);
}
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
float radius, float height, boolean solid, int nrOfSlices,
List<Integer> bottomRingVertices, List<Integer> topRingVertices) {
addCylinderMesh(obj, transformer, groupName, radius, height, nrOfSlices, solid, bottomRingVertices, topRingVertices);
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
addCylinderMesh(obj, transformer, groupName, radius, height, nrOfSlices, solid, foreRingVertices, aftRingVertices);
}
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,

View File

@ -6,6 +6,7 @@ import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.DefaultObjFace;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import java.util.ArrayList;
import java.util.List;
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.
* @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 aftOuterRadius The outer radius of the aft (bottom) 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
* 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 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 topOuterVertices A list to add the indices of the top 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 topInnerVertices A list to add the indices of the top inner 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 aftOuterVertices A list to add the indices of the aft (bottom) outer 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 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,
float aftOuterRadius, float foreOuterRadius,
float aftInnerRadius, float foreInnerRadius, float length, int numSides,
List<Integer> bottomOuterVertices, List<Integer> topOuterVertices,
List<Integer> bottomInnerVertices, List<Integer> topInnerVertices) {
if (aftInnerRadius > aftOuterRadius || foreInnerRadius > foreOuterRadius) {
float foreOuterRadius, float aftOuterRadius,
float foreInnerRadius, float aftInnerRadius, float length, int numSides,
List<Integer> foreOuterVertices, List<Integer> aftOuterVertices,
List<Integer> foreInnerVertices, List<Integer> aftInnerVertices) {
if (Float.compare(aftInnerRadius, aftOuterRadius) > 0 || Float.compare(foreInnerRadius, foreOuterRadius) > 0) {
throw new IllegalArgumentException("Inner radius must be less than outer radius");
}
@ -41,102 +44,38 @@ public class TubeExporter {
obj.setActiveGroupNames(groupName);
}
// Other meshes may have been added to the obj, so we need to keep track of the starting indices
int startIdx = obj.getNumVertices();
int normalsStartIdx = obj.getNumNormals();
obj.addNormal(transformer.convertLocWithoutOriginOffs(-1, 0, 0)); // Top faces normal
obj.addNormal(transformer.convertLocWithoutOriginOffs(1, 0, 0)); // Bottom faces normal
// Generate top outside vertices
generateRingVertices(obj, transformer, startIdx, numSides, 0, foreOuterRadius, true, topOuterVertices);
// Generate top inside vertices
generateRingVertices(obj, transformer, startIdx + numSides, numSides, 0, foreInnerRadius, false, topInnerVertices);
// 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);
// We need to store the vertices to create the closing disks, so we'll create lists if they do not exist
if (foreOuterVertices == null) {
foreOuterVertices = new ArrayList<>();
}
if (aftOuterVertices == null) {
aftOuterVertices = new ArrayList<>();
}
if (foreInnerVertices == null) {
foreInnerVertices = new ArrayList<>();
}
if (aftInnerVertices == null) {
aftInnerVertices = new ArrayList<>();
}
// Create bottom faces
for (int i = 0; i < numSides; i++) {
int[] vertexIndices = new int[] {
2*numSides + i, // Bottom-left of quad outside vertex
3*numSides + i, // Top-left of quad inside vertex
3*numSides + ((i + 1) % numSides), // Top-right of quad inside vertex
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);
// Generate inside mesh
boolean hasForeThickness = Float.compare(foreOuterRadius, foreInnerRadius) > 0 && Float.compare(foreInnerRadius, 0) > 0;
boolean hasAftThickness = Float.compare(aftOuterRadius, aftInnerRadius) > 0 && Float.compare(aftInnerRadius, 0) > 0;
if (hasForeThickness || hasAftThickness) {
CylinderExporter.addCylinderMesh(obj, transformer, null, foreInnerRadius, aftInnerRadius, length, numSides,
false, false, foreInnerVertices, aftInnerVertices);
}
// Create outside side faces
for (int i = 0; i < numSides; i++) {
final int nextIdx = (i + 1) % numSides;
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);
// Generate outside mesh
CylinderExporter.addCylinderMesh(obj, transformer, null, foreOuterRadius, aftOuterRadius, length, numSides,
!hasForeThickness && !hasAftThickness, true, foreOuterVertices, aftOuterVertices);
int[] normalIndices = 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(normalIndices, normalsStartIdx + 2); // Extra 2 offset for bottom and top normals
DefaultObjFace face = new DefaultObjFace(vertexIndices, null, normalIndices);
obj.addFace(face);
// Close the mesh
if (hasForeThickness) {
DiskExporter.closeDiskMesh(obj, transformer, null, foreOuterVertices, foreInnerVertices, false, true);
}
// Create inside side faces
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);
if (hasAftThickness) {
DiskExporter.closeDiskMesh(obj, transformer, null, aftOuterVertices, aftInnerVertices, false, false);
}
}

View File

@ -12,7 +12,6 @@ import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.OpenRocketDocumentFactory;
import net.sf.openrocket.file.GeneralRocketLoader;
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.wavefrontobj.CoordTransform;
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.TubeFinSet;
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.Test;
@ -47,13 +44,8 @@ import java.util.List;
import static org.junit.Assert.fail;
public class OBJExporterFactoryTest {
private final OpenRocketSaver saver = new OpenRocketSaver();
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
public static void setup() {
Module applicationModule = new ServicesForTesting();
@ -68,10 +60,10 @@ 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);
if( !(TMP_DIR.exists() && TMP_DIR.isDirectory()) ){
if (!(TMP_DIR.exists() && TMP_DIR.isDirectory())) {
boolean success = TMP_DIR.mkdirs();
if (!success) {
fail("Unable to create core/tmp dir needed for tests.");
@ -81,6 +73,7 @@ public class OBJExporterFactoryTest {
@Test
public void testExport() throws IOException {
// Rocket generation
Rocket rocket = OpenRocketDocumentFactory.createNewRocket().getRocket();
AxialStage sustainer = rocket.getStage(0);
@ -156,43 +149,35 @@ public class OBJExporterFactoryTest {
InnerTube innerTube = new 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);
// Create a temp file for storing the exported OBJ
Path tempFile = Files.createTempFile("testExport", ".obj");
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());
OBJExporterFactory exporterFactory = new OBJExporterFactory(components, rocket.getSelectedConfiguration(), true, false, true,
transformer, filePath);
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());
exporterFactory = new OBJExporterFactory(components, false, false, true,
exporterFactory = new OBJExporterFactory(components, rocket.getSelectedConfiguration(), false, false, true,
transformer, filePath);
exporterFactory.doExport();*/
exporterFactory.doExport();
// Clean up
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;
}
}