Add Wavefront OBJ support, to supplement the existing STL mesh
export. That doesn't seem very useful, but it's only a few dozen lines of code. [git-p4: depot-paths = "//depot/solvespace/": change = 2054]
This commit is contained in:
parent
83bbc004dc
commit
f6bb680978
75
export.cpp
75
export.cpp
|
@ -340,19 +340,6 @@ double VectorFileWriter::MmToPts(double mm) {
|
||||||
return (mm/25.4)*72;
|
return (mm/25.4)*72;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VectorFileWriter::StringEndsIn(char *str, char *ending) {
|
|
||||||
int i, ls = strlen(str), le = strlen(ending);
|
|
||||||
|
|
||||||
if(ls < le) return false;
|
|
||||||
|
|
||||||
for(i = 0; i < le; i++) {
|
|
||||||
if(tolower(ending[le-i-1]) != tolower(str[ls-i-1])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorFileWriter *VectorFileWriter::ForFile(char *filename) {
|
VectorFileWriter *VectorFileWriter::ForFile(char *filename) {
|
||||||
VectorFileWriter *ret;
|
VectorFileWriter *ret;
|
||||||
if(StringEndsIn(filename, ".dxf")) {
|
if(StringEndsIn(filename, ".dxf")) {
|
||||||
|
@ -552,8 +539,7 @@ void VectorFileWriter::BezierAsNonrationalCubic(DWORD rgb, double width,
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Export the mesh as an STL file; it should always be vertex-to-vertex and
|
// Export a triangle mesh, in the requested format.
|
||||||
// not self-intersecting, so not much to do.
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SolveSpace::ExportMeshTo(char *filename) {
|
void SolveSpace::ExportMeshTo(char *filename) {
|
||||||
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
|
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
|
||||||
|
@ -567,18 +553,36 @@ void SolveSpace::ExportMeshTo(char *filename) {
|
||||||
Error("Couldn't write to '%s'", filename);
|
Error("Couldn't write to '%s'", filename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(StringEndsIn(filename, ".stl")) {
|
||||||
|
ExportMeshAsStlTo(f, m);
|
||||||
|
} else if(StringEndsIn(filename, ".obj")) {
|
||||||
|
ExportMeshAsObjTo(f, m);
|
||||||
|
} else {
|
||||||
|
Error("Can't identify output file type from file extension of "
|
||||||
|
"filename '%s'; try .stl, .obj.", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Export the mesh as an STL file; it should always be vertex-to-vertex and
|
||||||
|
// not self-intersecting, so not much to do.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void SolveSpace::ExportMeshAsStlTo(FILE *f, SMesh *sm) {
|
||||||
char str[80];
|
char str[80];
|
||||||
memset(str, 0, sizeof(str));
|
memset(str, 0, sizeof(str));
|
||||||
strcpy(str, "STL exported mesh");
|
strcpy(str, "STL exported mesh");
|
||||||
fwrite(str, 1, 80, f);
|
fwrite(str, 1, 80, f);
|
||||||
|
|
||||||
DWORD n = m->l.n;
|
DWORD n = sm->l.n;
|
||||||
fwrite(&n, 4, 1, f);
|
fwrite(&n, 4, 1, f);
|
||||||
|
|
||||||
double s = SS.exportScale;
|
double s = SS.exportScale;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(i = 0; i < sm->l.n; i++) {
|
||||||
STriangle *tr = &(m->l.elem[i]);
|
STriangle *tr = &(sm->l.elem[i]);
|
||||||
Vector n = tr->Normal().WithMagnitude(1);
|
Vector n = tr->Normal().WithMagnitude(1);
|
||||||
float w;
|
float w;
|
||||||
w = (float)n.x; fwrite(&w, 4, 1, f);
|
w = (float)n.x; fwrite(&w, 4, 1, f);
|
||||||
|
@ -596,8 +600,41 @@ void SolveSpace::ExportMeshTo(char *filename) {
|
||||||
fputc(0, f);
|
fputc(0, f);
|
||||||
fputc(0, f);
|
fputc(0, f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fclose(f);
|
//-----------------------------------------------------------------------------
|
||||||
|
// Export the mesh as Wavefront OBJ format. This requires us to reduce all the
|
||||||
|
// identical vertices to the same identifier, so do that first.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void SolveSpace::ExportMeshAsObjTo(FILE *f, SMesh *sm) {
|
||||||
|
SPointList spl;
|
||||||
|
ZERO(&spl);
|
||||||
|
STriangle *tr;
|
||||||
|
for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) {
|
||||||
|
spl.IncrementTagFor(tr->a);
|
||||||
|
spl.IncrementTagFor(tr->b);
|
||||||
|
spl.IncrementTagFor(tr->c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output all the vertices.
|
||||||
|
SPoint *sp;
|
||||||
|
for(sp = spl.l.First(); sp; sp = spl.l.NextAfter(sp)) {
|
||||||
|
fprintf(f, "v %.10f %.10f %.10f\r\n",
|
||||||
|
sp->p.x / SS.exportScale,
|
||||||
|
sp->p.y / SS.exportScale,
|
||||||
|
sp->p.z / SS.exportScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// And now all the triangular faces, in terms of those vertices. The
|
||||||
|
// file format counts from 1, not 0.
|
||||||
|
for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) {
|
||||||
|
fprintf(f, "f %d %d %d\r\n",
|
||||||
|
spl.IndexForPoint(tr->a) + 1,
|
||||||
|
spl.IndexForPoint(tr->b) + 1,
|
||||||
|
spl.IndexForPoint(tr->c) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
spl.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
14
polygon.cpp
14
polygon.cpp
|
@ -313,13 +313,19 @@ void SPointList::Clear(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SPointList::ContainsPoint(Vector pt) {
|
bool SPointList::ContainsPoint(Vector pt) {
|
||||||
SPoint *p;
|
return (IndexForPoint(pt) >= 0);
|
||||||
for(p = l.First(); p; p = l.NextAfter(p)) {
|
}
|
||||||
|
|
||||||
|
int SPointList::IndexForPoint(Vector pt) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < l.n; i++) {
|
||||||
|
SPoint *p = &(l.elem[i]);
|
||||||
if(pt.Equals(p->p)) {
|
if(pt.Equals(p->p)) {
|
||||||
return true;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
// Not found, so return negative to indicate that.
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPointList::IncrementTagFor(Vector pt) {
|
void SPointList::IncrementTagFor(Vector pt) {
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
|
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
bool ContainsPoint(Vector pt);
|
bool ContainsPoint(Vector pt);
|
||||||
|
int IndexForPoint(Vector pt);
|
||||||
void IncrementTagFor(Vector pt);
|
void IncrementTagFor(Vector pt);
|
||||||
void Add(Vector pt);
|
void Add(Vector pt);
|
||||||
};
|
};
|
||||||
|
|
|
@ -435,7 +435,7 @@ void SolveSpace::MenuFile(int id) {
|
||||||
|
|
||||||
case GraphicsWindow::MNU_EXPORT_MESH: {
|
case GraphicsWindow::MNU_EXPORT_MESH: {
|
||||||
char exportFile[MAX_PATH] = "";
|
char exportFile[MAX_PATH] = "";
|
||||||
if(!GetSaveFile(exportFile, STL_EXT, STL_PATTERN)) break;
|
if(!GetSaveFile(exportFile, MESH_EXT, MESH_PATTERN)) break;
|
||||||
SS.ExportMeshTo(exportFile);
|
SS.ExportMeshTo(exportFile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
10
solvespace.h
10
solvespace.h
|
@ -82,8 +82,10 @@ int SaveFileYesNoCancel(void);
|
||||||
#define PNG_PATTERN "PNG (*.png)\0*.png\0All Files (*)\0*\0\0"
|
#define PNG_PATTERN "PNG (*.png)\0*.png\0All Files (*)\0*\0\0"
|
||||||
#define PNG_EXT "png"
|
#define PNG_EXT "png"
|
||||||
// Triangle mesh
|
// Triangle mesh
|
||||||
#define STL_PATTERN "STL Mesh (*.stl)\0*.stl\0All Files (*)\0*\0\0"
|
#define MESH_PATTERN "STL Mesh (*.stl)\0*.stl\0" \
|
||||||
#define STL_EXT "stl"
|
"Wavefront OBJ Mesh (*.obj)\0*.obj\0" \
|
||||||
|
"All Files (*)\0*\0\0"
|
||||||
|
#define MESH_EXT "stl"
|
||||||
// NURBS surfaces
|
// NURBS surfaces
|
||||||
#define SRF_PATTERN "STEP File (*.step;*.stp)\0*.step;*.stp\0" \
|
#define SRF_PATTERN "STEP File (*.step;*.stp)\0*.step;*.stp\0" \
|
||||||
"All Files(*)\0*\0\0"
|
"All Files(*)\0*\0\0"
|
||||||
|
@ -228,6 +230,7 @@ void MakeMatrix(double *mat, double a11, double a12, double a13, double a14,
|
||||||
void MakePathRelative(char *base, char *path);
|
void MakePathRelative(char *base, char *path);
|
||||||
void MakePathAbsolute(char *base, char *path);
|
void MakePathAbsolute(char *base, char *path);
|
||||||
bool StringAllPrintable(char *str);
|
bool StringAllPrintable(char *str);
|
||||||
|
bool StringEndsIn(char *str, char *ending);
|
||||||
|
|
||||||
class System {
|
class System {
|
||||||
public:
|
public:
|
||||||
|
@ -406,7 +409,6 @@ public:
|
||||||
Vector ptMin, ptMax;
|
Vector ptMin, ptMax;
|
||||||
|
|
||||||
static double MmToPts(double mm);
|
static double MmToPts(double mm);
|
||||||
static bool StringEndsIn(char *str, char *ending);
|
|
||||||
|
|
||||||
static VectorFileWriter *ForFile(char *file);
|
static VectorFileWriter *ForFile(char *file);
|
||||||
|
|
||||||
|
@ -629,6 +631,8 @@ public:
|
||||||
// And the various export options
|
// And the various export options
|
||||||
void ExportAsPngTo(char *file);
|
void ExportAsPngTo(char *file);
|
||||||
void ExportMeshTo(char *file);
|
void ExportMeshTo(char *file);
|
||||||
|
void ExportMeshAsStlTo(FILE *f, SMesh *sm);
|
||||||
|
void ExportMeshAsObjTo(FILE *f, SMesh *sm);
|
||||||
void ExportViewOrWireframeTo(char *file, bool wireframe);
|
void ExportViewOrWireframeTo(char *file, bool wireframe);
|
||||||
void ExportSectionTo(char *file);
|
void ExportSectionTo(char *file);
|
||||||
void ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl,
|
void ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl,
|
||||||
|
|
14
util.cpp
14
util.cpp
|
@ -88,6 +88,20 @@ bool StringAllPrintable(char *str)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StringEndsIn(char *str, char *ending)
|
||||||
|
{
|
||||||
|
int i, ls = strlen(str), le = strlen(ending);
|
||||||
|
|
||||||
|
if(ls < le) return false;
|
||||||
|
|
||||||
|
for(i = 0; i < le; i++) {
|
||||||
|
if(tolower(ending[le-i-1]) != tolower(str[ls-i-1])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void MakeMatrix(double *mat, double a11, double a12, double a13, double a14,
|
void MakeMatrix(double *mat, double a11, double a12, double a13, double a14,
|
||||||
double a21, double a22, double a23, double a24,
|
double a21, double a22, double a23, double a24,
|
||||||
double a31, double a32, double a33, double a34,
|
double a31, double a32, double a33, double a34,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user