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;
|
||||
}
|
||||
|
||||
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 *ret;
|
||||
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
|
||||
// not self-intersecting, so not much to do.
|
||||
// Export a triangle mesh, in the requested format.
|
||||
//-----------------------------------------------------------------------------
|
||||
void SolveSpace::ExportMeshTo(char *filename) {
|
||||
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
|
||||
|
@ -567,18 +553,36 @@ void SolveSpace::ExportMeshTo(char *filename) {
|
|||
Error("Couldn't write to '%s'", filename);
|
||||
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];
|
||||
memset(str, 0, sizeof(str));
|
||||
strcpy(str, "STL exported mesh");
|
||||
fwrite(str, 1, 80, f);
|
||||
|
||||
DWORD n = m->l.n;
|
||||
DWORD n = sm->l.n;
|
||||
fwrite(&n, 4, 1, f);
|
||||
|
||||
double s = SS.exportScale;
|
||||
int i;
|
||||
for(i = 0; i < m->l.n; i++) {
|
||||
STriangle *tr = &(m->l.elem[i]);
|
||||
for(i = 0; i < sm->l.n; i++) {
|
||||
STriangle *tr = &(sm->l.elem[i]);
|
||||
Vector n = tr->Normal().WithMagnitude(1);
|
||||
float w;
|
||||
w = (float)n.x; fwrite(&w, 4, 1, f);
|
||||
|
@ -596,8 +600,41 @@ void SolveSpace::ExportMeshTo(char *filename) {
|
|||
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) {
|
||||
SPoint *p;
|
||||
for(p = l.First(); p; p = l.NextAfter(p)) {
|
||||
return (IndexForPoint(pt) >= 0);
|
||||
}
|
||||
|
||||
int SPointList::IndexForPoint(Vector pt) {
|
||||
int i;
|
||||
for(i = 0; i < l.n; i++) {
|
||||
SPoint *p = &(l.elem[i]);
|
||||
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) {
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
|
||||
void Clear(void);
|
||||
bool ContainsPoint(Vector pt);
|
||||
int IndexForPoint(Vector pt);
|
||||
void IncrementTagFor(Vector pt);
|
||||
void Add(Vector pt);
|
||||
};
|
||||
|
|
|
@ -435,7 +435,7 @@ void SolveSpace::MenuFile(int id) {
|
|||
|
||||
case GraphicsWindow::MNU_EXPORT_MESH: {
|
||||
char exportFile[MAX_PATH] = "";
|
||||
if(!GetSaveFile(exportFile, STL_EXT, STL_PATTERN)) break;
|
||||
if(!GetSaveFile(exportFile, MESH_EXT, MESH_PATTERN)) break;
|
||||
SS.ExportMeshTo(exportFile);
|
||||
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_EXT "png"
|
||||
// Triangle mesh
|
||||
#define STL_PATTERN "STL Mesh (*.stl)\0*.stl\0All Files (*)\0*\0\0"
|
||||
#define STL_EXT "stl"
|
||||
#define MESH_PATTERN "STL Mesh (*.stl)\0*.stl\0" \
|
||||
"Wavefront OBJ Mesh (*.obj)\0*.obj\0" \
|
||||
"All Files (*)\0*\0\0"
|
||||
#define MESH_EXT "stl"
|
||||
// NURBS surfaces
|
||||
#define SRF_PATTERN "STEP File (*.step;*.stp)\0*.step;*.stp\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 MakePathAbsolute(char *base, char *path);
|
||||
bool StringAllPrintable(char *str);
|
||||
bool StringEndsIn(char *str, char *ending);
|
||||
|
||||
class System {
|
||||
public:
|
||||
|
@ -406,7 +409,6 @@ public:
|
|||
Vector ptMin, ptMax;
|
||||
|
||||
static double MmToPts(double mm);
|
||||
static bool StringEndsIn(char *str, char *ending);
|
||||
|
||||
static VectorFileWriter *ForFile(char *file);
|
||||
|
||||
|
@ -629,6 +631,8 @@ public:
|
|||
// And the various export options
|
||||
void ExportAsPngTo(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 ExportSectionTo(char *file);
|
||||
void ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl,
|
||||
|
|
14
util.cpp
14
util.cpp
|
@ -88,6 +88,20 @@ bool StringAllPrintable(char *str)
|
|||
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,
|
||||
double a21, double a22, double a23, double a24,
|
||||
double a31, double a32, double a33, double a34,
|
||||
|
|
Loading…
Reference in New Issue
Block a user