diff options
Diffstat (limited to 'Magic2/MagicDoc.cpp')
-rw-r--r-- | Magic2/MagicDoc.cpp | 1254 |
1 files changed, 639 insertions, 615 deletions
diff --git a/Magic2/MagicDoc.cpp b/Magic2/MagicDoc.cpp index 7b8e6f8..f0c7929 100644 --- a/Magic2/MagicDoc.cpp +++ b/Magic2/MagicDoc.cpp @@ -1,615 +1,639 @@ -/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: MagicDoc.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Implementation of the MagicDoc class
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-
-#include "MagicDoc.h"
-#include "ModelFileMAG.h"
-#include "ModelFileOBJ.h"
-#include "ModelFile3DS.h"
-#include "Selection.h"
-#include "Selector.h"
-#include "Editor.h"
-#include "Command.h"
-
-#include "Bitmap.h"
-#include "Color.h"
-#include "D3DXImage.h"
-#include "Geometry.h"
-#include "Pcx.h"
-#include "Polygon.h"
-#include "Solid.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-// +--------------------------------------------------------------------+
-
-IMPLEMENT_DYNCREATE(MagicDoc, CDocument)
-
-BEGIN_MESSAGE_MAP(MagicDoc, CDocument)
- //{{AFX_MSG_MAP(MagicDoc)
- ON_COMMAND(ID_SURFACE_OPTIMIZE, OnSurfaceOptimize)
- ON_COMMAND(ID_SURFACE_EXPLODE, OnSurfaceExplode)
- ON_UPDATE_COMMAND_UI(ID_SURFACE_OPTIMIZE, OnUpdateSurfaceOptimize)
- ON_UPDATE_COMMAND_UI(ID_SURFACE_EXPLODE, OnUpdateSurfaceExplode)
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-// +--------------------------------------------------------------------+
-
-MagicDoc::MagicDoc()
- : solid(0), selection(0)
-{
- solid = new Solid;
- selection = new Selection;
- selector = new Selector(selection);
- editor = new Editor(this);
-}
-
-MagicDoc::~MagicDoc()
-{
- if (editor) delete editor;
- if (selector) delete selector;
- if (selection) delete selection;
- if (solid) delete solid;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-MagicDoc::InitCommandStack()
-{
- nundo = 0;
- commands.destroy();
-}
-
-void
-MagicDoc::Exec(Command* command)
-{
- int nredo = commands.size() - nundo;
-
- while (nredo) {
- delete commands.removeIndex(commands.size()-1);
- nredo--;
- }
-
- if (nundo < 100) {
- nundo++;
- }
- else {
- delete commands.removeIndex(0);
- }
-
- command->Do();
- commands.append(command);
-}
-
-int
-MagicDoc::NumUndo() const
-{
- return nundo;
-}
-
-int
-MagicDoc::NumRedo() const
-{
- return commands.size() - nundo;
-}
-
-const char*
-MagicDoc::GetUndoName() const
-{
- if (nundo > 0 && nundo <= commands.size())
- return commands[nundo-1]->Name();
- else
- return "";
-}
-
-const char*
-MagicDoc::GetRedoName() const
-{
- if (nundo >= 0 && nundo < commands.size())
- return commands[nundo]->Name();
- else
- return "";
-}
-
-void
-MagicDoc::Undo()
-{
- if (nundo > 0 && nundo <= commands.size())
- commands[--nundo]->Undo();
-}
-
-void
-MagicDoc::Redo()
-{
- if (nundo >= 0 && nundo < commands.size())
- commands[nundo++]->Do();
-}
-
-// +--------------------------------------------------------------------+
-
-BOOL MagicDoc::OnNewDocument()
-{
- if (!CDocument::OnNewDocument())
- return FALSE;
-
- InitCommandStack();
-
- if (solid) delete solid;
- solid = new Solid;
-
- if (selection)
- selection->Clear();
-
- return TRUE;
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicDoc::Serialize(CArchive& ar)
-{
-}
-
-// +--------------------------------------------------------------------+
-
-#ifdef _DEBUG
-void MagicDoc::AssertValid() const
-{
- CDocument::AssertValid();
-}
-
-void MagicDoc::Dump(CDumpContext& dc) const
-{
- CDocument::Dump(dc);
-}
-#endif //_DEBUG
-
-// +--------------------------------------------------------------------+
-
-BOOL MagicDoc::OnSaveDocument(LPCTSTR path_name)
-{
- SetModifiedFlag(FALSE);
-
- ModelFileMAG mod_file(path_name);
- mod_file.Save(solid->GetModel());
-
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- return TRUE;
-}
-
-BOOL MagicDoc::OnOpenDocument(LPCTSTR path_name)
-{
- FILE* fp = fopen(path_name, "rb");
- if (!fp) {
- ::MessageBox(0, "Open Failed: could not open file", "ERROR", MB_OK);
- return FALSE;
- }
-
- int version = 1;
- char file_id[5];
- fread(file_id, 4, 1, fp);
- file_id[4] = '\0';
- fclose(fp);
-
- if (strncmp(file_id, "MAG", 3)) {
- ::MessageBox(0, "Open Failed: Invalid file type", "ERROR", MB_OK);
- return FALSE;
- }
-
- switch (file_id[3]) {
- case '6': version = 6; break;
- case '5': version = 5; break;
- default: version = 0; break;
- }
-
- if (version < 5 || version > 6) {
- ::MessageBox(0, "Open Failed: Unsupported version", "ERROR", MB_OK);
- return FALSE;
- }
-
- DeleteContents();
-
- ModelFileMAG mod_file(path_name);
- solid->Load(&mod_file);
- solid->CreateShadows();
-
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- return TRUE;
-}
-
-bool
-MagicDoc::ImportFile(LPCTSTR path_name)
-{
- if (strstr(path_name, ".obj") || strstr(path_name, ".OBJ")) {
- ModelFileOBJ obj_file(path_name);
-
- if (solid->GetModel()) {
- Solid* s = new Solid;
-
- if (s->Load(&obj_file)) {
- // todo: insert command here
- Model* orig = solid->GetModel();
- Model* imported = s->GetModel();
-
- orig->GetMaterials().append(imported->GetMaterials());
- orig->GetSurfaces().append(imported->GetSurfaces());
- orig->OptimizeMaterials();
-
- imported->GetMaterials().clear();
- imported->GetSurfaces().clear();
-
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- delete s;
- return true;
- }
-
- delete s;
- }
- else {
- if (solid->Load(&obj_file)) {
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- return true;
- }
- }
-
- return false;
- }
-
- if (strstr(path_name, ".3ds") || strstr(path_name, ".3DS")) {
- ModelFile3DS model_file(path_name);
-
- if (solid->GetModel()) {
- Solid* s = new Solid;
-
- if (s->Load(&model_file)) {
- // todo: insert command here
- Model* orig = solid->GetModel();
- Model* imported = s->GetModel();
-
- orig->GetMaterials().append(imported->GetMaterials());
- orig->GetSurfaces().append(imported->GetSurfaces());
- orig->OptimizeMaterials();
-
- imported->GetMaterials().clear();
- imported->GetSurfaces().clear();
-
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- delete s;
- return true;
- }
-
- delete s;
- }
- else {
- if (solid->Load(&model_file)) {
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- return true;
- }
- }
-
- return false;
- }
-
- FILE* fp = fopen(path_name, "rb");
- if (!fp) {
- ::MessageBox(0, "Import Failed: could not open file", "ERROR", MB_OK);
- return false;
- }
-
- int version = 1;
- char file_id[5];
- fread(file_id, 4, 1, fp);
- file_id[4] = '\0';
- fclose(fp);
-
- if (strncmp(file_id, "MAG", 3)) {
- ::MessageBox(0, "Open Failed: Invalid file type", "ERROR", MB_OK);
- return false;
- }
-
- switch (file_id[3]) {
- case '6': version = 6; break;
- case '5': version = 5; break;
- default: version = 0; break;
- }
-
- if (version < 5 || version > 6) {
- ::MessageBox(0, "Open Failed: Unsupported version", "ERROR", MB_OK);
- return false;
- }
-
- ModelFileMAG mag_file(path_name);
-
- if (solid->GetModel()) {
- Solid* s = new Solid;
- if (s->Load(&mag_file)) {
- // todo: insert command here
- Model* orig = solid->GetModel();
- Model* imported = s->GetModel();
-
- orig->GetMaterials().append(imported->GetMaterials());
- orig->GetSurfaces().append(imported->GetSurfaces());
- orig->OptimizeMaterials();
-
- imported->GetMaterials().clear();
- imported->GetSurfaces().clear();
-
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- delete s;
- return true;
- }
-
- delete s;
- }
- else {
- InitCommandStack();
-
- if (solid->Load(&mag_file)) {
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- return true;
- }
- }
-
- return false;
-}
-
-bool
-MagicDoc::ExportFile(LPCTSTR path_name)
-{
- if (!solid->GetModel())
- return false;
-
- if (strstr(path_name, ".obj") || strstr(path_name, ".OBJ")) {
- ModelFileOBJ obj_file(path_name);
- obj_file.Save(solid->GetModel());
- return true;
- }
-
- if (strstr(path_name, ".3ds") || strstr(path_name, ".3DS")) {
- return false;
- }
-
- if (strstr(path_name, ".mag") || strstr(path_name, ".MAG")) {
- ModelFileMAG mod_file(path_name);
- mod_file.Save(solid->GetModel());
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-int LoadBuffer(const char* filename, BYTE*& buf, bool null_terminate)
-{
- buf = 0;
-
- FILE* f = ::fopen(filename, "rb");
-
- if (f) {
- ::fseek(f, 0, SEEK_END);
- int len = ftell(f);
- ::fseek(f, 0, SEEK_SET);
-
- if (null_terminate) {
- buf = new BYTE[len+1];
- if (buf)
- buf[len] = 0;
- }
-
- else {
- buf = new BYTE[len];
- }
-
- if (buf)
- ::fread(buf, len, 1, f);
-
- ::fclose(f);
-
- return len;
- }
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicDoc::DeleteContents()
-{
- CDocument::DeleteContents();
- InitCommandStack();
-
- if (solid) {
- delete solid;
- solid = new Solid;
- }
-
- if (selection)
- selection->Clear();
-}
-
-// +--------------------------------------------------------------------+
-
-int LoadTexture(const char* fname, Bitmap*& bitmap, int type)
-{
- int result = 0;
-
- if (!fname || !*fname)
- return result;
-
- bitmap = Bitmap::CheckCache(fname);
-
- if (!bitmap) {
- bool pcx_file = strstr(fname, ".pcx") || strstr(fname, ".PCX");
-
- // handle PCX formats:
- if (pcx_file) {
- PcxImage pcx;
-
- if (pcx.Load((char*) fname) == PCX_OK) {
- bitmap = new Bitmap;
-
- // 32-bit image
- if (pcx.himap) {
- bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap);
- }
-
- // 8-bit image, check for 32-bit image as well
- else if (pcx.bitmap) {
- bitmap->CopyImage(pcx.width, pcx.height, pcx.bitmap);
-
- char tmp[256];
- int len = strlen(fname);
- bool found = false;
-
- ZeroMemory(tmp, sizeof(tmp));
-
- for (int i = 0; i < len && !found; i++) {
- if (strstr(fname + i, ".pcx") == (fname+i)) {
- found = true;
- }
- else {
- tmp[i] = fname[i];
- }
- }
-
- if (found) {
- strcat_s(tmp, "+.pcx");
- if (pcx.Load(tmp) == PCX_OK && pcx.himap != 0) {
- bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap);
- }
- }
- }
- }
- }
-
- // for all other formats, use D3DX:
- else {
- D3DXImage d3dx;
- if (d3dx.Load((char*) fname)) {
- bitmap = new Bitmap;
- bitmap->CopyHighColorImage(d3dx.width, d3dx.height, d3dx.image);
- }
- }
-
- if (bitmap) {
- LoadAlpha(fname, *bitmap, type);
-
- bitmap->SetFilename(fname);
- bitmap->SetType(type);
- bitmap->MakeTexture();
-
- Bitmap::AddToCache(bitmap);
- }
- }
-
- return result;
-}
-
-int LoadAlpha(const char* name, Bitmap& bitmap, int type)
-{
- PcxImage pcx;
- D3DXImage d3dx;
- bool pcx_file = strstr(name, ".pcx") || strstr(name, ".PCX");
- bool bmp_file = strstr(name, ".bmp") || strstr(name, ".BMP");
- bool jpg_file = strstr(name, ".jpg") || strstr(name, ".JPG");
- bool png_file = strstr(name, ".png") || strstr(name, ".PNG");
- bool tga_file = strstr(name, ".tga") || strstr(name, ".TGA");
-
- // check for an associated alpha-only (grayscale) bitmap:
- char filename[256];
- strcpy_s(filename, name);
-
- char* dot = strrchr(filename, '.');
- if (dot && pcx_file)
- strcpy(dot, "@.pcx");
- else if (dot && bmp_file)
- strcpy(dot, "@.bmp");
- else if (dot && jpg_file)
- strcpy(dot, "@.jpg");
- else if (dot && png_file)
- strcpy(dot, "@.png");
- else if (dot && tga_file)
- strcpy(dot, "@.tga");
- else
- return 0;
-
- // first try to load from current directory:
- bool loaded = false;
-
- if (pcx_file)
- loaded = pcx.Load(filename) == PCX_OK;
-
- else
- loaded = d3dx.Load(filename);
-
- // now copy the alpha values into the bitmap:
- if (loaded) {
- if (pcx_file && pcx.bitmap) {
- bitmap.CopyAlphaImage(pcx.width, pcx.height, pcx.bitmap);
- }
- else if (pcx_file && pcx.himap) {
- bitmap.CopyAlphaRedChannel(pcx.width, pcx.height, pcx.himap);
- }
- else if (d3dx.image) {
- bitmap.CopyAlphaRedChannel(d3dx.width, d3dx.height, d3dx.image);
- }
- }
-
- return 0;
-}
-
-
-void MagicDoc::OnSurfaceOptimize()
-{
- if (solid && solid->GetModel()) {
- solid->GetModel()->OptimizeMesh();
- solid->InvalidateSurfaceData();
- solid->InvalidateSegmentData();
- }
-}
-
-void MagicDoc::OnUpdateSurfaceOptimize(CCmdUI* pCmdUI)
-{
- pCmdUI->Enable(solid && solid->GetModel());
-}
-
-void MagicDoc::OnSurfaceExplode()
-{
- if (solid && solid->GetModel()) {
- solid->GetModel()->ExplodeMesh();
- solid->InvalidateSurfaceData();
- solid->InvalidateSegmentData();
- }
-}
-
-void MagicDoc::OnUpdateSurfaceExplode(CCmdUI* pCmdUI)
-{
- pCmdUI->Enable(solid && solid->GetModel());
-}
+/* Starshatter OpenSource Distribution + Copyright (c) 1997-2004, Destroyer Studios LLC. + All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name "Destroyer Studios" nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + SUBSYSTEM: Magic.exe + FILE: MagicDoc.cpp + AUTHOR: John DiCamillo + + + OVERVIEW + ======== + Implementation of the MagicDoc class +*/ + +#include "stdafx.h" +#include "Magic.h" + +#include "MagicDoc.h" +#include "ModelFileMAG.h" +#include "ModelFileOBJ.h" +#include "ModelFile3DS.h" +#include "Selection.h" +#include "Selector.h" +#include "Editor.h" +#include "Command.h" + +#include "Bitmap.h" +#include "Color.h" +#include "D3DXImage.h" +#include "Geometry.h" +#include "Pcx.h" +#include "Polygon.h" +#include "Solid.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// +--------------------------------------------------------------------+ + +IMPLEMENT_DYNCREATE(MagicDoc, CDocument) + +BEGIN_MESSAGE_MAP(MagicDoc, CDocument) + //{{AFX_MSG_MAP(MagicDoc) + ON_COMMAND(ID_SURFACE_OPTIMIZE, OnSurfaceOptimize) + ON_COMMAND(ID_SURFACE_EXPLODE, OnSurfaceExplode) + ON_UPDATE_COMMAND_UI(ID_SURFACE_OPTIMIZE, OnUpdateSurfaceOptimize) + ON_UPDATE_COMMAND_UI(ID_SURFACE_EXPLODE, OnUpdateSurfaceExplode) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// +--------------------------------------------------------------------+ + +MagicDoc::MagicDoc() + : solid(0), selection(0) +{ + solid = new Solid; + selection = new Selection; + selector = new Selector(selection); + editor = new Editor(this); +} + +MagicDoc::~MagicDoc() +{ + if (editor) delete editor; + if (selector) delete selector; + if (selection) delete selection; + if (solid) delete solid; +} + +// +--------------------------------------------------------------------+ + +void +MagicDoc::InitCommandStack() +{ + nundo = 0; + commands.destroy(); +} + +void +MagicDoc::Exec(Command* command) +{ + int nredo = commands.size() - nundo; + + while (nredo) { + delete commands.removeIndex(commands.size()-1); + nredo--; + } + + if (nundo < 100) { + nundo++; + } + else { + delete commands.removeIndex(0); + } + + command->Do(); + commands.append(command); +} + +int +MagicDoc::NumUndo() const +{ + return nundo; +} + +int +MagicDoc::NumRedo() const +{ + return commands.size() - nundo; +} + +const char* +MagicDoc::GetUndoName() const +{ + if (nundo > 0 && nundo <= commands.size()) + return commands[nundo-1]->Name(); + else + return ""; +} + +const char* +MagicDoc::GetRedoName() const +{ + if (nundo >= 0 && nundo < commands.size()) + return commands[nundo]->Name(); + else + return ""; +} + +void +MagicDoc::Undo() +{ + if (nundo > 0 && nundo <= commands.size()) + commands[--nundo]->Undo(); +} + +void +MagicDoc::Redo() +{ + if (nundo >= 0 && nundo < commands.size()) + commands[nundo++]->Do(); +} + +// +--------------------------------------------------------------------+ + +BOOL MagicDoc::OnNewDocument() +{ + if (!CDocument::OnNewDocument()) + return FALSE; + + InitCommandStack(); + + if (solid) delete solid; + solid = new Solid; + + if (selection) + selection->Clear(); + + return TRUE; +} + +// +--------------------------------------------------------------------+ + +void MagicDoc::Serialize(CArchive& ar) +{ +} + +// +--------------------------------------------------------------------+ + +#ifdef _DEBUG +void MagicDoc::AssertValid() const +{ + CDocument::AssertValid(); +} + +void MagicDoc::Dump(CDumpContext& dc) const +{ + CDocument::Dump(dc); +} +#endif //_DEBUG + +// +--------------------------------------------------------------------+ + +BOOL MagicDoc::OnSaveDocument(LPCTSTR path_name) +{ + SetModifiedFlag(FALSE); + + ModelFileMAG mod_file(path_name); + mod_file.Save(solid->GetModel()); + + SetModifiedFlag(FALSE); + UpdateAllViews(NULL); + return TRUE; +} + +BOOL MagicDoc::OnOpenDocument(LPCTSTR path_name) +{ + FILE* fp = fopen(path_name, "rb"); + if (!fp) { + ::MessageBox(0, "Open Failed: could not open file", "ERROR", MB_OK); + return FALSE; + } + + int version = 1; + char file_id[5]; + fread(file_id, 4, 1, fp); + file_id[4] = '\0'; + fclose(fp); + + if (strncmp(file_id, "MAG", 3)) { + ::MessageBox(0, "Open Failed: Invalid file type", "ERROR", MB_OK); + return FALSE; + } + + switch (file_id[3]) { + case '6': version = 6; break; + case '5': version = 5; break; + default: version = 0; break; + } + + if (version < 5 || version > 6) { + ::MessageBox(0, "Open Failed: Unsupported version", "ERROR", MB_OK); + return FALSE; + } + + DeleteContents(); + + ModelFileMAG mod_file(path_name); + solid->Load(&mod_file); + solid->CreateShadows(); + + SetModifiedFlag(FALSE); + UpdateAllViews(NULL); + return TRUE; +} + +bool +MagicDoc::ImportFile(LPCTSTR path_name) +{ + if (strstr(path_name, ".obj") || strstr(path_name, ".OBJ")) { + ModelFileOBJ obj_file(path_name); + + if (solid->GetModel()) { + Solid* s = new Solid; + + if (s->Load(&obj_file)) { + // todo: insert command here + Model* orig = solid->GetModel(); + Model* imported = s->GetModel(); + + orig->GetMaterials().append(imported->GetMaterials()); + orig->GetSurfaces().append(imported->GetSurfaces()); + orig->OptimizeMaterials(); + + imported->GetMaterials().clear(); + imported->GetSurfaces().clear(); + + SetModifiedFlag(FALSE); + UpdateAllViews(NULL); + delete s; + return true; + } + + delete s; + } + else { + if (solid->Load(&obj_file)) { + SetModifiedFlag(FALSE); + UpdateAllViews(NULL); + return true; + } + } + + return false; + } + + if (strstr(path_name, ".3ds") || strstr(path_name, ".3DS")) { + ModelFile3DS model_file(path_name); + + if (solid->GetModel()) { + Solid* s = new Solid; + + if (s->Load(&model_file)) { + // todo: insert command here + Model* orig = solid->GetModel(); + Model* imported = s->GetModel(); + + orig->GetMaterials().append(imported->GetMaterials()); + orig->GetSurfaces().append(imported->GetSurfaces()); + orig->OptimizeMaterials(); + + imported->GetMaterials().clear(); + imported->GetSurfaces().clear(); + + SetModifiedFlag(FALSE); + UpdateAllViews(NULL); + delete s; + return true; + } + + delete s; + } + else { + if (solid->Load(&model_file)) { + SetModifiedFlag(FALSE); + UpdateAllViews(NULL); + return true; + } + } + + return false; + } + + FILE* fp = fopen(path_name, "rb"); + if (!fp) { + ::MessageBox(0, "Import Failed: could not open file", "ERROR", MB_OK); + return false; + } + + int version = 1; + char file_id[5]; + fread(file_id, 4, 1, fp); + file_id[4] = '\0'; + fclose(fp); + + if (strncmp(file_id, "MAG", 3)) { + ::MessageBox(0, "Open Failed: Invalid file type", "ERROR", MB_OK); + return false; + } + + switch (file_id[3]) { + case '6': version = 6; break; + case '5': version = 5; break; + default: version = 0; break; + } + + if (version < 5 || version > 6) { + ::MessageBox(0, "Open Failed: Unsupported version", "ERROR", MB_OK); + return false; + } + + ModelFileMAG mag_file(path_name); + + if (solid->GetModel()) { + Solid* s = new Solid; + if (s->Load(&mag_file)) { + // todo: insert command here + Model* orig = solid->GetModel(); + Model* imported = s->GetModel(); + + orig->GetMaterials().append(imported->GetMaterials()); + orig->GetSurfaces().append(imported->GetSurfaces()); + orig->OptimizeMaterials(); + + imported->GetMaterials().clear(); + imported->GetSurfaces().clear(); + + SetModifiedFlag(FALSE); + UpdateAllViews(NULL); + delete s; + return true; + } + + delete s; + } + else { + InitCommandStack(); + + if (solid->Load(&mag_file)) { + SetModifiedFlag(FALSE); + UpdateAllViews(NULL); + return true; + } + } + + return false; +} + +bool +MagicDoc::ExportFile(LPCTSTR path_name) +{ + if (!solid->GetModel()) + return false; + + if (strstr(path_name, ".obj") || strstr(path_name, ".OBJ")) { + ModelFileOBJ obj_file(path_name); + obj_file.Save(solid->GetModel()); + return true; + } + + if (strstr(path_name, ".3ds") || strstr(path_name, ".3DS")) { + return false; + } + + if (strstr(path_name, ".mag") || strstr(path_name, ".MAG")) { + ModelFileMAG mod_file(path_name); + mod_file.Save(solid->GetModel()); + return true; + } + + return false; +} + +// +--------------------------------------------------------------------+ + +int LoadBuffer(const char* filename, BYTE*& buf, bool null_terminate) +{ + buf = 0; + + FILE* f = ::fopen(filename, "rb"); + + if (f) { + ::fseek(f, 0, SEEK_END); + int len = ftell(f); + ::fseek(f, 0, SEEK_SET); + + if (null_terminate) { + buf = new BYTE[len+1]; + if (buf) + buf[len] = 0; + } + + else { + buf = new BYTE[len]; + } + + if (buf) + ::fread(buf, len, 1, f); + + ::fclose(f); + + return len; + } + + return 0; +} + +// +--------------------------------------------------------------------+ + +void MagicDoc::DeleteContents() +{ + CDocument::DeleteContents(); + InitCommandStack(); + + if (solid) { + delete solid; + solid = new Solid; + } + + if (selection) + selection->Clear(); +} + +// +--------------------------------------------------------------------+ + +int LoadTexture(const char* fname, Bitmap*& bitmap, int type) +{ + int result = 0; + + if (!fname || !*fname) + return result; + + bitmap = Bitmap::CheckCache(fname); + + if (!bitmap) { + bool pcx_file = strstr(fname, ".pcx") || strstr(fname, ".PCX"); + + // handle PCX formats: + if (pcx_file) { + PcxImage pcx; + + if (pcx.Load((char*) fname) == PCX_OK) { + bitmap = new Bitmap; + + // 32-bit image + if (pcx.himap) { + bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap); + } + + // 8-bit image, check for 32-bit image as well + else if (pcx.bitmap) { + bitmap->CopyImage(pcx.width, pcx.height, pcx.bitmap); + + char tmp[256]; + int len = strlen(fname); + bool found = false; + + ZeroMemory(tmp, sizeof(tmp)); + + for (int i = 0; i < len && !found; i++) { + if (strstr(fname + i, ".pcx") == (fname+i)) { + found = true; + } + else { + tmp[i] = fname[i]; + } + } + + if (found) { + strcat_s(tmp, "+.pcx"); + if (pcx.Load(tmp) == PCX_OK && pcx.himap != 0) { + bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap); + } + } + } + } + } + + // for all other formats, use D3DX: + else { + D3DXImage d3dx; + if (d3dx.Load((char*) fname)) { + bitmap = new Bitmap; + bitmap->CopyHighColorImage(d3dx.width, d3dx.height, d3dx.image); + } + } + + if (bitmap) { + LoadAlpha(fname, *bitmap, type); + + bitmap->SetFilename(fname); + bitmap->SetType(type); + bitmap->MakeTexture(); + + Bitmap::AddToCache(bitmap); + } + } + + return result; +} + +int LoadAlpha(const char* name, Bitmap& bitmap, int type) +{ + PcxImage pcx; + D3DXImage d3dx; + bool pcx_file = strstr(name, ".pcx") || strstr(name, ".PCX"); + bool bmp_file = strstr(name, ".bmp") || strstr(name, ".BMP"); + bool jpg_file = strstr(name, ".jpg") || strstr(name, ".JPG"); + bool png_file = strstr(name, ".png") || strstr(name, ".PNG"); + bool tga_file = strstr(name, ".tga") || strstr(name, ".TGA"); + + // check for an associated alpha-only (grayscale) bitmap: + char filename[256]; + strcpy_s(filename, name); + + char* dot = strrchr(filename, '.'); + if (dot && pcx_file) + strcpy(dot, "@.pcx"); + else if (dot && bmp_file) + strcpy(dot, "@.bmp"); + else if (dot && jpg_file) + strcpy(dot, "@.jpg"); + else if (dot && png_file) + strcpy(dot, "@.png"); + else if (dot && tga_file) + strcpy(dot, "@.tga"); + else + return 0; + + // first try to load from current directory: + bool loaded = false; + + if (pcx_file) + loaded = pcx.Load(filename) == PCX_OK; + + else + loaded = d3dx.Load(filename); + + // now copy the alpha values into the bitmap: + if (loaded) { + if (pcx_file && pcx.bitmap) { + bitmap.CopyAlphaImage(pcx.width, pcx.height, pcx.bitmap); + } + else if (pcx_file && pcx.himap) { + bitmap.CopyAlphaRedChannel(pcx.width, pcx.height, pcx.himap); + } + else if (d3dx.image) { + bitmap.CopyAlphaRedChannel(d3dx.width, d3dx.height, d3dx.image); + } + } + + return 0; +} + + +void MagicDoc::OnSurfaceOptimize() +{ + if (solid && solid->GetModel()) { + solid->GetModel()->OptimizeMesh(); + solid->InvalidateSurfaceData(); + solid->InvalidateSegmentData(); + } +} + +void MagicDoc::OnUpdateSurfaceOptimize(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(solid && solid->GetModel()); +} + +void MagicDoc::OnSurfaceExplode() +{ + if (solid && solid->GetModel()) { + solid->GetModel()->ExplodeMesh(); + solid->InvalidateSurfaceData(); + solid->InvalidateSegmentData(); + } +} + +void MagicDoc::OnUpdateSurfaceExplode(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(solid && solid->GetModel()); +} |