shithub: libobj

Download patch

ref: 4c0fa932d419096fcac897b37631187d03441ce5
parent: b538f9954c0c62d840a9c898f5302d3128420171
author: rodri <rgl@antares-labs.eu>
date: Wed Jun 18 20:23:20 EDT 2025

finish OBJMaterlistfmt(). create an OBJTexture type.

with this new type we can store the original texture
file name and use it when exporting or converting to
other formats.

--- a/obj.c
+++ b/obj.c
@@ -19,6 +19,9 @@
 	ulong line;
 };
 
+static OBJVertex ZV;
+static OBJColor ZC;
+
 static void
 error(Line *l, char *fmt, ...)
 {
@@ -166,6 +169,23 @@
 	return nil;
 }
 
+static OBJTexture *
+readtexturefile(char *path)
+{
+	OBJTexture *t;
+	char *s;
+
+	t = emalloc(sizeof *t);
+	t->image = readimagefile(path);
+	if(t->image == nil){
+		werrstr("readimagefile: %r");
+		return nil;
+	}
+	s = strrchr(path, '/');
+	t->filename = s == nil? estrdup(path): estrdup(++s);
+	return t;
+}
+
 static void
 addvertva(OBJVertexArray *va, OBJVertex v)
 {
@@ -278,6 +298,15 @@
 	return o;
 }
 
+static void
+freetex(OBJTexture *t)
+{
+	if(t == nil)
+		return;
+	free(t->filename);
+	freememimage(t->image);
+}
+
 static OBJMaterial *
 allocmt(char *name)
 {
@@ -292,9 +321,9 @@
 static void
 freemt(OBJMaterial *m)
 {
-	freememimage(m->norm);
-	freememimage(m->map_Ks);
-	freememimage(m->map_Kd);
+	freetex(m->norm);
+	freetex(m->map_Ks);
+	freetex(m->map_Kd);
 	free(m->name);
 	free(m);
 }
@@ -497,8 +526,8 @@
 				goto error;
 			}
 			snprint(buf, sizeof buf, "%s/%s", wdir, f[1]);
-			if((m->map_Kd = readimagefile(buf)) == nil){
-				error(&curline, "readimagefile: %r");
+			if((m->map_Kd = readtexturefile(buf)) == nil){
+				error(&curline, "readtexturefile: %r");
 				goto error;
 			}
 		}else if(strcmp(f[0], "map_Ks") == 0){
@@ -511,8 +540,8 @@
 				goto error;
 			}
 			snprint(buf, sizeof buf, "%s/%s", wdir, f[1]);
-			if((m->map_Ks = readimagefile(buf)) == nil){
-				error(&curline, "readimagefile: %r");
+			if((m->map_Ks = readtexturefile(buf)) == nil){
+				error(&curline, "readtexturefile: %r");
 				goto error;
 			}
 		}else if(strcmp(f[0], "norm") == 0){
@@ -525,8 +554,8 @@
 				goto error;
 			}
 			snprint(buf, sizeof buf, "%s/%s", wdir, f[1]);
-			if((m->norm = readimagefile(buf)) == nil){
-				error(&curline, "readimagefile: %r");
+			if((m->norm = readtexturefile(buf)) == nil){
+				error(&curline, "readtexturefile: %r");
 				goto error;
 			}
 		}else if(strcmp(f[0], "illum") == 0){
@@ -974,17 +1003,28 @@
 	for(i = 0; i < nelem(ml->mattab); i++)
 		for(m = ml->mattab[i]; m != nil; m = m->next){
 			n += fmtprint(f, "newmtl %s\n", m->name);
-			n += fmtprint(f, "Ka %g %g %g\n", m->Ka.r, m->Ka.g, m->Ka.b);
-			n += fmtprint(f, "Kd %g %g %g\n", m->Kd.r, m->Kd.g, m->Kd.b);
-			n += fmtprint(f, "Ks %g %g %g\n", m->Ks.r, m->Ks.g, m->Ks.b);
-			n += fmtprint(f, "Ke %g %g %g\n", m->Ke.r, m->Ke.g, m->Ke.b);
-			n += fmtprint(f, "Ns %g\n", m->Ns);
-			n += fmtprint(f, "Ni %g\n", m->Ni);
-			n += fmtprint(f, "d %g\n", m->d);
-			n += fmtprint(f, "illum %d\n", m->illum);
-			n += fmtprint(f, "map_Kd %s_diffuse.png\n", m->name);
-			n += fmtprint(f, "map_Ks %s_specular.png\n", m->name);
-			n += fmtprint(f, "norm %s_normal.png\n", m->name);
+			if(memcmp(&m->Ka, &ZC, sizeof(ZC)) != 0)
+				n += fmtprint(f, "Ka %g %g %g\n", m->Ka.r, m->Ka.g, m->Ka.b);
+			if(memcmp(&m->Kd, &ZC, sizeof(ZC)) != 0)
+				n += fmtprint(f, "Kd %g %g %g\n", m->Kd.r, m->Kd.g, m->Kd.b);
+			if(memcmp(&m->Ks, &ZC, sizeof(ZC)) != 0)
+				n += fmtprint(f, "Ks %g %g %g\n", m->Ks.r, m->Ks.g, m->Ks.b);
+			if(memcmp(&m->Ke, &ZC, sizeof(ZC)) != 0)
+				n += fmtprint(f, "Ke %g %g %g\n", m->Ke.r, m->Ke.g, m->Ke.b);
+			if(m->Ns != 0)
+				n += fmtprint(f, "Ns %g\n", m->Ns);
+			if(m->Ni != 0)
+				n += fmtprint(f, "Ni %g\n", m->Ni);
+			if(m->d != 0)
+				n += fmtprint(f, "d %g\n", m->d);
+			if(m->illum != 0)
+				n += fmtprint(f, "illum %d\n", m->illum);
+			if(m->map_Kd != nil)
+				n += fmtprint(f, "map_Kd %s\n", m->map_Kd->filename);
+			if(m->map_Ks != nil)
+				n += fmtprint(f, "map_Ks %s\n", m->map_Ks->filename);
+			if(m->norm != nil)
+				n += fmtprint(f, "norm %s\n", m->norm->filename);
 			n += fmtprint(f, "\n");
 		}
 
@@ -1002,6 +1042,7 @@
 
 	n = pack = 0;
 	obj = va_arg(f->args, OBJ*);
+
 	for(i = 0; i < nelem(obj->vertdata); i++)
 		for(j = 0; j < obj->vertdata[i].nvert; j++){
 			v = obj->vertdata[i].verts[j];
@@ -1020,8 +1061,10 @@
 				break;
 			}
 		}
+
 	if(obj->materials != nil)
 		n += fmtprint(f, "mtllib %s\n", obj->materials->filename);
+
 	for(i = 0; i < nelem(obj->objtab); i++)
 		for(o = obj->objtab[i]; o != nil; o = o->next){
 			if(strcmp(o->name, "default") != 0)
@@ -1061,6 +1104,7 @@
 					n += fmtprint(f, "\n");
 			}
 		}
+
 	return n;
 }
 
@@ -1068,4 +1112,5 @@
 OBJfmtinstall(void)
 {
 	fmtinstall('O', OBJfmt);
+	fmtinstall('M', OBJMaterlistfmt);
 }
--- a/obj.h
+++ b/obj.h
@@ -6,6 +6,7 @@
 	OBJVParametric,
 	OBJNVERT
 };
+
 /* element types */
 enum {
 	OBJEPoint,
@@ -15,6 +16,7 @@
 	OBJECurve2,
 	OBJESurface
 };
+
 /* grouping types */
 enum {
 	OBJGGlobal,
@@ -21,6 +23,7 @@
 	OBJGSmoothing,
 	OBJGMerging
 };
+
 /* object hash table size */
 enum {
 	OBJHTSIZE = 17
@@ -28,6 +31,7 @@
 
 typedef union OBJVertex OBJVertex;
 typedef struct OBJColor OBJColor;
+typedef struct OBJTexture OBJTexture;
 typedef struct OBJVertexArray OBJVertexArray;
 typedef struct OBJIndexArray OBJIndexArray;
 typedef struct OBJMaterial OBJMaterial;
@@ -38,6 +42,7 @@
 typedef struct OBJ OBJ;
 
 #pragma varargck type "O" OBJ*
+#pragma varargck type "M" OBJMaterlist*
 
 union OBJVertex
 {
@@ -51,6 +56,12 @@
 	double r, g, b, a;
 };
 
+struct OBJTexture
+{
+	Memimage *image;
+	char *filename;
+};
+
 struct OBJVertexArray
 {
 	OBJVertex *verts;
@@ -74,9 +85,9 @@
 	double Ni;		/* index of refraction */
 	double d;		/* dissolution factor (opacity) */
 	int illum;		/* illumination model */
-	Memimage *map_Kd;	/* color texture file */
-	Memimage *map_Ks;	/* specular texture file */
-	Memimage *norm;		/* normal texture file */
+	OBJTexture *map_Kd;	/* color texture file */
+	OBJTexture *map_Ks;	/* specular texture file */
+	OBJTexture *norm;	/* normal texture file */
 	OBJMaterial *next;
 };
 
--