Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches

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>
// 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];
Material()
{
sprintf(name, "");
color[0] = color[1] = color[2] = 0;
}
~Material() {}
};
// Chunk structure
typedef struct _Chunk {
} Chunk;
// vertex structure
typedef struct _Vertex {
Float_t x, y, z;
// face structure
typedef struct _Face {
} Face;
// model structure
class Model {
public:
char name[256];
char matname[256];
{
sprintf(name, "");
vlist = 0;
flist = 0;
}
{
if (vlist != 0)
delete[] vlist;
if (flist != 0)
delete[] flist;
}
};
// chunk reading routines
Int_t ReadChunk(FILE *, Chunk *);
// data reading routines
Int_t ReadASCIIZ(FILE *, char *);
// global variables
Model model;
Material *material[1024];
//______________________________________________________________________________
Int_t Read3DSFile(const char *fname)
{
// main function
infile = fopen(fname, "rb");
if (infile == 0) {
printf("Error : Input File Could Not Be Opened!\n");
return -1;
}
if (ReadMainChunk(infile) != 0) {
printf("Error : Input File Could Not Be Read!\n");
}
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);
}
//______________________________________________________________________________
{
// handles the main body of the 3DS file
Chunk 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;
}
//______________________________________________________________________________
{
// 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;
}
//______________________________________________________________________________
{
// 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) {
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;
}
}
}
return 0;
}
//______________________________________________________________________________
{
// 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;
}
//______________________________________________________________________________
{
// reads the Transparency property of the Material Chunk
Chunk chunk;
float ftransp;
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;
}
//______________________________________________________________________________
{
// reads the name of material associated to the current Chunk
ReadASCIIZ(f, model.matname);
return 0;
}
//______________________________________________________________________________
{
// reads the Object sub-chunk of the 3D Edit Chunk
Chunk chunk;
char name[256];
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;
}
//______________________________________________________________________________
{
// 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))) {
} else if (chunk.idnum == CHUNK3DOBJECTMESHFACES) {
} else if (chunk.idnum == CHUNK3DOBJECTMESHMAPPING) {
} else if (chunk.idnum == CHUNK3DOBJECTMESHMATGROUP) {
} else {
if (chunk.endoffset < len) {
// printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum);
fseek(f, chunk.endoffset, SEEK_SET);
} else {
break;
}
}
}
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, "");
return 0;
}
//______________________________________________________________________________
{
// reads Vertex data of the TriMesh Chunk
Int_t i;
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;
}
//______________________________________________________________________________
{
// 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;
}
//______________________________________________________________________________
{
// reads Texture Mapping data of the TriMesh Chunk
UShort_t numuv = 0, i;
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;
}
//______________________________________________________________________________
{
// 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;
}
//______________________________________________________________________________
{
// 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]->GenerateTriangleNormals();
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
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
R__EXTERN TEveManager * gEve
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
char name[80]
Definition TGX11.cxx:110
virtual void AddElement(TEveElement *el)
Add el to the list of children.
void AddElement(TEveElement *element, TEveElement *parent=nullptr)
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)
Made from a list of vertices and a list of triangles (triplets of vertex indices).
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.