Loading [MathJax]/extensions/tex2jax.js
Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
view3ds.C File Reference

Detailed Description

Loading and display of basic 3DS models.

#include "TCanvas.h"
#include "TStyle.h"
#include "TFile.h"
#include "TStopwatch.h"
#include "TError.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
TEveTriangleSet *ts[2048];
// Believe3D Model file defines
#define MAGICNUMBER 0xB3D0
// types of 3DS Chunks
#define CHUNKMAIN 0x4D4D
#define CHUNKMAINVERSION 0x0002
#define CHUNK3D 0x3D3D
#define CHUNK3DVERSION 0x3D3E
#define CHUNK3DOBJECT 0x4000
#define CHUNK3DOBJECTMESH 0x4100
#define CHUNK3DOBJECTMESHVERTICES 0x4110
#define CHUNK3DOBJECTMESHFACES 0x4120
#define CHUNK3DOBJECTMESHMATGROUP 0x4130
#define CHUNK3DOBJECTMESHMAPPING 0x4140
#define CHUNK3DMATERIAL 0xAFFF
// Sub defines of MATERIAL
#define MATNAME 0xA000
#define MATDIFFUSE 0xA020
#define MATSPECULAR 0xA030
#define MATTRANSPARENCY 0xA050
#define COLOR_F 0x0010
#define COLOR_24 0x0011
#define LIN_COLOR_24 0x0012
#define LIN_COLOR_F 0x0013
#define INT_PERCENTAGE 0x0030
#define FLOAT_PERCENTAGE 0x0031
//////////////////////////////////////
//The tMaterialInfo Struct
//////////////////////////////////////
class Material {
public:
char name[256];
UChar_t color[3];
UShort_t transparency;
Material() {
sprintf(name, "");
color[0] = color[1] = color[2] = 0;
transparency = 0;
}
~Material() { }
};
// Chunk structure
typedef struct _Chunk {
UShort_t idnum;
UInt_t offset, len, endoffset;
} Chunk;
// vertex structure
typedef struct _Vertex {
Float_t x, y, z;
Float_t u, v;
// face structure
typedef struct _Face {
} Face;
// model structure
class Model {
public:
char name[256];
char matname[256];
Vertex *vlist;
Face *flist;
UInt_t numverts, numfaces;
Model() {
sprintf(name,"");
sprintf(matname,"");
vlist = 0;
flist = 0;
numverts = numfaces = 0;
}
~Model() {
if (vlist != 0) delete [] vlist;
if (flist != 0) delete [] flist;
}
};
// chunk reading routines
Int_t ReadChunk(FILE*, Chunk*);
// data reading routines
Int_t ReadMainChunk(FILE*);
Int_t Read3DChunk(FILE*, UInt_t);
Int_t ReadObjectChunk(FILE*, UInt_t);
Int_t ReadMeshChunk(FILE*, UInt_t, char*);
Int_t ReadVerticesChunk(FILE*);
Int_t ReadFacesChunk(FILE*);
Int_t ReadMappingChunk(FILE*);
Int_t ReadASCIIZ(FILE*, char*);
Int_t ReadMaterialChunk(FILE *, UInt_t);
Int_t ReadColor(FILE *, UInt_t);
Int_t ReadTransparency(FILE *, UInt_t);
Int_t ReadObjectMaterial(FILE *);
Int_t ConvertModel();
// global variables
Int_t nummodels = 0;
Model model;
Int_t nummaterials = 0;
Material *material[1024];
//______________________________________________________________________________
Int_t Read3DSFile(const char *fname)
{
// main function
FILE *infile;
infile = fopen(fname, "rb");
if (infile == 0) {
printf("Error : Input File Could Not Be Opened!\n");
return -1;
}
UShort_t magic = MAGICNUMBER;
if (ReadMainChunk(infile) != 0) {
printf("Error : Input File Could Not Be Read!\n");
}
fclose(infile);
return 0;
}
//______________________________________________________________________________
Int_t ReadChunk(FILE *f, Chunk *c)
{
// reads a chunk from an opened file
if (feof(f)) return(-1);
c->idnum = 0;
c->offset = c->len = 0;
c->offset = (UInt_t) ftell(f);
fread(&c->idnum, sizeof(UShort_t), 1, f);
fread(&c->len, sizeof(UInt_t), 1, f);
c->endoffset = c->offset + c->len;
return(0);
}
//______________________________________________________________________________
Int_t ReadMainChunk(FILE *f)
{
// handles the main body of the 3DS file
Chunk chunk;
ReadChunk(f, &chunk);
if (chunk.idnum != CHUNKMAIN) return(-1);
while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
if (chunk.idnum == CHUNK3D) {
Read3DChunk(f, chunk.endoffset);
}
else {
//printf("Debug : Unknown Chunk [Main Chunk] [0x%x]\n", chunk.idnum);
fseek(f, chunk.offset + chunk.len, SEEK_SET);
}
}
return 0;
}
//______________________________________________________________________________
Int_t Read3DChunk(FILE *f, UInt_t len)
{
// reads the 3D Edit Chunk
Chunk chunk;
while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
if (chunk.idnum == CHUNK3DOBJECT) {
ReadObjectChunk(f, chunk.endoffset);
fseek(f, chunk.endoffset, SEEK_SET);
}
else if (chunk.idnum == CHUNK3DMATERIAL) {
ReadMaterialChunk(f, chunk.endoffset);
fseek(f, chunk.endoffset, SEEK_SET);
}
else {
if (chunk.endoffset < len) {
//printf("Debug : Unknown Chunk [3D Chunk] [0x%x]\n", chunk.idnum);
fseek(f, chunk.endoffset, SEEK_SET);
}
else {
break;
}
}
}
return 0;
}
//______________________________________________________________________________
Int_t ReadMaterialChunk(FILE *f, UInt_t len)
{
// reads the Material sub-chunk of the 3D Edit Chunk
Chunk chunk;
char name[256];
material[nummaterials] = new Material();
while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
if (chunk.idnum == MATNAME) {
ReadASCIIZ(f, name);
strcpy(material[nummaterials]->name, name);
fseek(f, chunk.endoffset, SEEK_SET);
}
else if (chunk.idnum == MATDIFFUSE) {
ReadColor(f, chunk.endoffset);
fseek(f, chunk.endoffset, SEEK_SET);
}
else if (chunk.idnum == MATTRANSPARENCY) {
ReadTransparency(f, chunk.endoffset);
fseek(f, chunk.endoffset, SEEK_SET);
}
else {
if (chunk.endoffset < len) {
//printf("Debug : Unknown Chunk [Object Chunk] [0x%x]\n", chunk.idnum);
fseek(f, chunk.endoffset, SEEK_SET);
}
else {
break;
}
}
}
nummaterials++;
return 0;
}
//______________________________________________________________________________
Int_t ReadColor(FILE *f, UInt_t len)
{
// reads the Color property of the Material Chunk
Chunk chunk;
float fr, fg, fb;
while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
if (chunk.idnum == LIN_COLOR_24) {
fread(&material[nummaterials]->color[0], sizeof(UChar_t), 1, f);
fread(&material[nummaterials]->color[1], sizeof(UChar_t), 1, f);
fread(&material[nummaterials]->color[2], sizeof(UChar_t), 1, f);
fseek(f, chunk.endoffset, SEEK_SET);
}
else if (chunk.idnum == COLOR_24) {
fread(&material[nummaterials]->color[0], sizeof(UChar_t), 1, f);
fread(&material[nummaterials]->color[1], sizeof(UChar_t), 1, f);
fread(&material[nummaterials]->color[2], sizeof(UChar_t), 1, f);
fseek(f, chunk.endoffset, SEEK_SET);
}
else if (chunk.idnum == LIN_COLOR_F) {
fread(&fr, sizeof(Float_t), 1, f);
fread(&fg, sizeof(Float_t), 1, f);
fread(&fb, sizeof(Float_t), 1, f);
fseek(f, chunk.endoffset, SEEK_SET);
}
else if (chunk.idnum == COLOR_F) {
fread(&fr, sizeof(Float_t), 1, f);
fread(&fg, sizeof(Float_t), 1, f);
fread(&fb, sizeof(Float_t), 1, f);
fseek(f, chunk.endoffset, SEEK_SET);
}
else {
if (chunk.endoffset < len) {
//printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum);
fseek(f, chunk.endoffset, SEEK_SET);
}
else {
break;
}
}
}
return 0;
}
//______________________________________________________________________________
Int_t ReadTransparency(FILE *f, UInt_t len)
{
// reads the Transparency property of the Material Chunk
Chunk chunk;
float ftransp;
UShort_t stransp;
while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
if (chunk.idnum == INT_PERCENTAGE) {
fread(&stransp, sizeof(UShort_t), 1, f);
material[nummaterials]->transparency = stransp;
fseek(f, chunk.endoffset, SEEK_SET);
}
else if (chunk.idnum == FLOAT_PERCENTAGE) {
fread(&ftransp, sizeof(float), 1, f);
fseek(f, chunk.endoffset, SEEK_SET);
}
else {
if (chunk.endoffset < len) {
//printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum);
fseek(f, chunk.endoffset, SEEK_SET);
}
else {
break;
}
}
}
return 0;
}
//______________________________________________________________________________
Int_t ReadObjectMaterial(FILE *f)
{
// reads the name of material associated to the current Chunk
ReadASCIIZ(f, model.matname);
return 0;
}
//______________________________________________________________________________
Int_t ReadObjectChunk(FILE *f, UInt_t len)
{
// reads the Object sub-chunk of the 3D Edit Chunk
Chunk chunk;
char name[256];
ReadASCIIZ(f, name);
while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
if (chunk.idnum == CHUNK3DOBJECTMESH) {
ReadMeshChunk(f, chunk.endoffset, name);
}
else {
if (chunk.endoffset < len) {
//printf("Debug : Unknown Chunk [Object Chunk] [0x%x]\n", chunk.idnum);
fseek(f, chunk.endoffset, SEEK_SET);
}
else {
break;
}
}
}
return 0;
}
//______________________________________________________________________________
Int_t ReadMeshChunk(FILE *f, UInt_t len, char *objname)
{
// reads the TriMesh sub-chunk of the Object Chunk
Chunk chunk;
model.vlist = 0;
model.flist = 0;
model.numverts = model.numfaces = 0;
sprintf(model.name, "%s", objname);
printf("Reading Mesh : %s\n", objname);
while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
if (chunk.idnum == CHUNK3DOBJECTMESHVERTICES) {
ReadVerticesChunk(f);
}
else if (chunk.idnum == CHUNK3DOBJECTMESHFACES) {
ReadFacesChunk(f);
}
else if (chunk.idnum == CHUNK3DOBJECTMESHMAPPING) {
ReadMappingChunk(f);
}
else if (chunk.idnum == CHUNK3DOBJECTMESHMATGROUP) {
ReadObjectMaterial(f);
}
else {
if (chunk.endoffset < len) {
//printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum);
fseek(f, chunk.endoffset, SEEK_SET);
}
else {
break;
}
}
}
ConvertModel();
if (model.vlist != 0) delete [] model.vlist;
if (model.flist != 0) delete [] model.flist;
model.vlist = 0;
model.flist = 0;
model.numverts = model.numfaces = 0;
sprintf(model.name,"");
nummodels++;
return 0;
}
//______________________________________________________________________________
Int_t ReadVerticesChunk(FILE *f)
{
// reads Vertex data of the TriMesh Chunk
Int_t i;
UShort_t numv = 0;
Float_t x, y, z;
fread(&numv, sizeof(UShort_t), 1, f);
printf("Reading %i Vertices...", numv);
model.vlist = new Vertex[numv];
if (model.vlist == 0) {
for (i = 0; i < numv; i++) {
fread(&x, sizeof(Float_t), 1, f);
fread(&y, sizeof(Float_t), 1, f);
fread(&z, sizeof(Float_t), 1, f);
}
printf("\nWarning : Insufficient Memory to Load Vertices!\n");
return -1;
}
for (i = 0; i < numv; i++) {
fread(&model.vlist[i].x, sizeof(Float_t), 1, f);
fread(&model.vlist[i].y, sizeof(Float_t), 1, f);
fread(&model.vlist[i].z, sizeof(Float_t), 1, f);
}
model.numverts = (UInt_t) numv;
printf("Done!\n");
return 0;
}
//______________________________________________________________________________
Int_t ReadFacesChunk(FILE *f)
{
// reads Face data of the TriMesh Chunk
Int_t i;
UShort_t numf = 0, v1, v2, v3, attr;
fread(&numf, sizeof(UShort_t), 1, f);
printf("Reading %i Faces...", numf);
model.flist = new Face[numf];
if (model.flist == 0) {
for (i = 0; i < numf; i++) {
fread(&v1, sizeof(UShort_t), 1, f);
fread(&v2, sizeof(UShort_t), 1, f);
fread(&v3, sizeof(UShort_t), 1, f);
fread(&attr, sizeof(UShort_t), 1, f);
}
printf("\nWarning : Insufficient Memory to Load Faces!\n");
return -1;
}
for (i = 0; i < numf; i++) {
fread(&v1, sizeof(UShort_t), 1, f);
fread(&v2, sizeof(UShort_t), 1, f);
fread(&v3, sizeof(UShort_t), 1, f);
fread(&attr, sizeof(UShort_t), 1, f);
model.flist[i].v1 = (UInt_t)(v1);
model.flist[i].v2 = (UInt_t)(v2);
model.flist[i].v3 = (UInt_t)(v3);
}
model.numfaces = (UInt_t)(numf);
printf("Done!\n");
return 0;
}
//______________________________________________________________________________
Int_t ReadMappingChunk(FILE *f)
{
// reads Texture Mapping data of the TriMesh Chunk
UShort_t numuv = 0, i;
Float_t u, v;
fread(&numuv, sizeof(UShort_t), 1, f);
printf("Reading %i Texture Coordinates...", numuv);
if (numuv != model.numverts) {
for (i = 0; i < numuv; i++) {
fread(&u, sizeof(Float_t), 1, f);
fread(&v, sizeof(Float_t), 1, f);
}
printf("\nWarning : Number of Vertices and Mapping Data do not match!\n");
return -1;
}
for (i = 0; i < numuv; i++) {
fread(&model.vlist[i].u, sizeof(Float_t), 1, f);
fread(&model.vlist[i].v, sizeof(Float_t), 1, f);
}
printf("Done!\n");
return 0;
}
//______________________________________________________________________________
Int_t ReadASCIIZ(FILE *f, char *name)
{
// reads a null-terminated string from the given file
char c = -1;
Int_t index = 0;
do {
fread(&c, sizeof(char), 1, f);
name[index] = c;
index++;
if (index == 255) {
name[index] = 0;
c = 0;
}
} while ((c != 0) && (!feof(f)));
return 0;
}
//______________________________________________________________________________
Int_t ConvertModel()
{
// Convert from Model structure to TEveTriangleSet
Int_t i;
ts[nummodels] = new TEveTriangleSet(model.numverts, model.numfaces);
if (ts[nummodels] == 0)
return -1;
for (i=0; i<model.numverts; ++i) {
ts[nummodels]->SetVertex(i, model.vlist[i].x, model.vlist[i].y,
model.vlist[i].z);
}
for (i=0; i<model.numfaces; ++i) {
ts[nummodels]->SetTriangle(i, model.flist[i].v1, model.flist[i].v2,
model.flist[i].v3);
}
ts[nummodels]->SetName(model.name);
ts[nummodels]->SetMainTransparency(0);
ts[nummodels]->SetMainColor(0);
for (i = 0; i < nummaterials; i++) {
if (strcmp(model.matname, material[i]->name) == 0) {
ts[nummodels]->SetMainTransparency(material[i]->transparency);
ts[nummodels]->SetMainColorRGB(material[i]->color[0],
material[i]->color[1],
material[i]->color[2]);
break;
}
}
return 0;
}
//______________________________________________________________________________
void view3ds(const char *fname = "nasashuttle.3ds")
{
// Main.
Int_t i;
for (i=0;i<2048;i++) ts[i] = 0;
for (i=0;i<1024;i++) material[i] = 0;
model.vlist = 0;
model.flist = 0;
nummodels = 0;
if (Read3DSFile(fname) == 0) {
TEveTriangleSet* parent = new TEveTriangleSet(0, 0);
parent->SetName(fname);
gEve->AddElement(parent);
for (i=0;i<nummodels;i++) {
if (ts[i]) {
ts[i]->RefMainTrans().RotateLF(1, 2, TMath::Pi());
parent->AddElement(ts[i]);
}
}
}
for (i = 0; i < nummaterials; i++)
if (material[i] != 0) delete material[i];
}
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
unsigned short UShort_t
Definition RtypesCore.h:40
int Int_t
Definition RtypesCore.h:45
unsigned char UChar_t
Definition RtypesCore.h:38
unsigned int UInt_t
Definition RtypesCore.h:46
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:100
R__EXTERN TEveManager * gEve
char name[80]
Definition TGX11.cxx:110
virtual void AddElement(TEveElement *el)
Add el to the list of children.
virtual void SetMainTransparency(Char_t t)
Set main-transparency.
virtual TEveTrans & RefMainTrans()
Return reference to main transformation.
virtual void SetMainColor(Color_t color)
Set main color of the element.
void SetMainColorRGB(UChar_t r, UChar_t g, UChar_t b)
Convert RGB values to Color_t and call SetMainColor.
void AddElement(TEveElement *element, TEveElement *parent=0)
Add an element.
static TEveManager * Create(Bool_t map_window=kTRUE, Option_t *opt="FIV")
If global TEveManager* gEve is not set initialize it.
void Redraw3D(Bool_t resetCameras=kFALSE, Bool_t dropLogicals=kFALSE)
void RotateLF(Int_t i1, Int_t i2, Double_t amount)
Rotate in local frame. Does optimised version of MultRight.
Made from a list of vertices and a list of triangles (triplets of vertex indices).
void SetTriangle(Int_t i, Int_t v0, Int_t v1, Int_t v2)
void SetVertex(Int_t i, Float_t x, Float_t y, Float_t z)
void GenerateTriangleNormals()
Generate triangle normals via cross product of triangle edges.
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
void Vertex(const Double_t *v)
constexpr Double_t Pi()
Definition TMath.h:37
Author
Bertrand Bellenot

Definition in file view3ds.C.