Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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:150
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.