Xrefutil Class Reference

DllEntry / xfrefutil

Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

Xrefutil Class Reference

#include <xrefutil.h>

Inheritance diagram for Xrefutil:

UtilityObj List of all members.

Public Methods

 Xrefutil ()
 ~Xrefutil ()
void BeginEditParams (Interface *ip,IUtil *iu)
void EndEditParams (Interface *ip,IUtil *iu)
void DeleteThis ()
void Init (HWND hWnd)
void Destroy (HWND hWnd)
bool DoOpenSaveDialog (TSTR &fileName, bool bOpen = false)
bool DoPickObjDialog ()
void AddNewXrefScene (HWND hWnd)
void ConvertSelectedToXrefScene (HWND hWnd)
void RefreshAllXrefScenes (HWND hWnd)
void MergeAllXrefScenes (HWND hWnd)
void NodeToXref (INode * pNode, TSTR &filename, bool bProxy, bool bIgnoreAnim = false)
void DeleteAllAnimation (ReferenceTarget *ref)
void AddNewXrefObject (HWND hWnd)
void ConvertSelectedToXrefObject (HWND hWnd)
void ExportXrefObjects (HWND hWnd)

Public Attributes

IUtil* m_pUtil
Interface* m_pInterface
HWND m_hPanel
Tab<TSTR *> m_objnamesholder
TSTR m_picknameholder
bool m_proxyholder
bool m_ignoreanimholder

Constructor & Destructor Documentation

Xrefutil::Xrefutil ( )
 

Definition at line 261 of file xrefutil.cpp.

00262 : m_pUtil(NULL)
00263 , m_pInterface(NULL)
00264 , m_hPanel(NULL)
00265 , m_proxyholder(false)
00266 , m_ignoreanimholder(false)

00267 {
00268 }

Xrefutil::~Xrefutil ( )
 

Definition at line 270 of file xrefutil.cpp.

00271 {
00272     
00273 }


Member Function Documentation

void Xrefutil::AddNewXrefObject ( HWND hWnd )
 

Definition at line 664 of file xrefutil.cpp.

00665 {
00666     // *** AddNewXrefObject ***
00667     //
00668     // Tries to mimic the functionality of MAX's Add New XRef Object
00669     // 
00670     // Does the following:
00671     // 1) Gets a source .MAX filename from user to get the XRef Object from
00672     // 1.5) Flags current nodes for later
00673     // 2) Merges in this file, but doesn't display end results (yet)
00674     // 3) Walks list of file nodes (not flagged), and lets user pick one to XRef
00675     // 4) Blows away all merged (not flagged) nodes except picked node.  Converts
00676     //    the chosen node into an XRef node (see ConvertSelectedToXrefObject below)
00677     //    with default settings
00678 
00679     INode * pNode = NULL;
00680     TSTR filename = "";
00681     TSTR pickedname = "";
00682     TSTR * workname = NULL;
00683 
00684     INode * pRootNode = m_pInterface->GetRootNode();
00685     if (!pRootNode) {
00686         // well, this is actually _really_ bad, but we just exit
00687         return;
00688     }
00689     if (!DoOpenSaveDialog(filename, true)) {
00690         // either cancel or fail, just return
00691         return;
00692     }
00693 
00694     // in preparation for merge, flag current scene nodes
00695     NodeFlagger newFlagger(A_WORK1);
00696     newFlagger.Enumerate(pRootNode);
00697 
00698     // merge in user-picked file into current scene
00699     // NOTE: We just skip anything in xref'd file that has the same name
00700     // as an object in the current scene
00701     if (! m_pInterface->MergeFromFile(filename, TRUE, FALSE, FALSE, MERGE_DUPS_SKIP, NULL)) {
00702         // error, merge failed
00703         newFlagger.set_clear(true);
00704         newFlagger.Enumerate(pRootNode);
00705         return;
00706     }
00707 
00708     // walk scene and build list of non-flagged nodes
00709     m_objnamesholder.ZeroCount();
00710         m_objnamesholder.Shrink();
00711     UnflaggedNodeNamer newNamer;
00712     newNamer.m_namelist = &m_objnamesholder;
00713     newNamer.Enumerate(pRootNode);
00714     UnflaggedNodeDeleter newDeleter;
00715 
00716     // present list of nodes to user, sep. modal dialog
00717     if (DoPickObjDialog() && m_picknameholder.length() > 0) {
00718         pNode = m_pInterface->GetINodeByName(m_picknameholder);
00719         if (pNode) {
00720             if (m_ignoreanimholder && pNode->IsAnimated()) {
00721                 // if animation is ignored, we basically go through
00722                 // the node and delete all the keys for the node's controllers
00723                 // Note that this won't remove animation for procedural controllers
00724                 DeleteAllAnimation(pNode);
00725             }
00726             NodeToXref(pNode, filename, m_proxyholder, m_ignoreanimholder);
00727             // flag this converted node so we keep it
00728             pNode->SetAFlag(A_WORK1);
00729         }
00730     }
00731 
00732     // deleted non-flagged nodes, un-flag original nodes, and return
00733     newDeleter.Enumerate(pRootNode);
00734     newFlagger.set_clear(true);
00735     newFlagger.Enumerate(pRootNode);
00736     for (int delme = 0; delme < m_objnamesholder.Count(); delme++) { 
00737         // (clean up TSTRs)
00738         delete m_objnamesholder[delme];
00739     }
00740 
00741     m_pInterface->RedrawViews(m_pInterface->GetTime());
00742 
00743 }

void Xrefutil::AddNewXrefScene ( HWND hWnd )
 

Definition at line 505 of file xrefutil.cpp.

00506 {
00507     // *** AddNewXrefScene ***
00508     //
00509     // Add new XRef'd Scene to current scene -- simply get the
00510     // name of the .MAX file, and use RootNode::AddNewXRefFile
00511     // to hook that xref'd scene into the current scene hierarchy
00512     //
00513     // Note: Don't confuse XRef scenes with XRef objects.
00514     // XRef scenes live as special children of the (single) root
00515     // node of the current scene, basically as "XRef'd root nodes"
00516     // of the external scene.  Note that merged-in XRef Root Nodes
00517     // can come from original scenes that already had another scene
00518     // xref'd in, and so-on.  See the SDK documentation on the 
00519     // various XRef Scene APIs on the INode object, keeping in mind
00520     // that these APIs only function when the INode is in fact the
00521     // root node of the scene.
00522     //
00523     
00524     TSTR filename = "";
00525     INode * pRootNode = m_pInterface->GetRootNode();
00526     if (!pRootNode) {
00527         // well, this is actually _really_ bad, but we just exit
00528         return;
00529     }
00530     if (!DoOpenSaveDialog(filename, true)) {
00531         // either cancel or fail, just return
00532         return;
00533     }    
00534     pRootNode->AddNewXRefFile(filename, TRUE);
00535     m_pInterface->RedrawViews(m_pInterface->GetTime());
00536 }

void Xrefutil::BeginEditParams ( Interface * ip,
IUtil * iu )
 

Definition at line 278 of file xrefutil.cpp.

00279 {
00280     m_pUtil = iu;
00281     m_pInterface = ip;
00282     m_hPanel = ip->AddRollupPage(hInstance,
00283                                MAKEINTRESOURCE(IDD_PANEL),
00284                                XrefutilDlgProc,
00285                                GetString(IDS_PARAMS),
00286                                0);
00287 }

void Xrefutil::ConvertSelectedToXrefObject ( HWND hWnd )
 

Definition at line 746 of file xrefutil.cpp.

00747 {
00748     // *** ConvertSelectedToXrefObject ***
00749     //
00750     // Takes single selection of scene object and
00751     // "converts" it to XRef Object with default settings.  This is 
00752     // done via the following steps:
00753     //
00754     // 1) Save selected object into new MAX file of user's specification
00755     // 2) Create a new XRefObject
00756     // 3) XRefObject makes reference to the objectref of the selected node (OSM-level only)
00757     // 4) INode object reference changed to XRefObject
00758     //
00759     // converting multiple selected objects is left as an exercise
00760     // but should be quite straight-forward...
00761 
00762     INode * pNode = NULL;
00763     TSTR filename = "";
00764 
00765     if (m_pInterface->GetSelNodeCount() != 1) {
00766         ::MessageBox(hWnd, GetString(IDS_ERR1), ERROR_TITLE, MB_ICONSTOP | MB_OK);
00767         return;
00768     }
00769     pNode = m_pInterface->GetSelNode(0);
00770     if (!pNode) {
00771         ::MessageBox(hWnd, GetString(IDS_ERR2), ERROR_TITLE, MB_ICONSTOP | MB_OK);
00772         return;
00773     }
00774 
00775     if (!DoOpenSaveDialog(filename)) {
00776         // either cancel or fail, just return
00777         return;
00778     }
00779     m_pInterface->FileSaveSelected(filename);
00780 
00781     // One caveat : If the object (not node) has any ReferenceMakers watching it
00782     // that are expecting geom pipeline msgs, you may need to remove/reset these
00783     // references.  After the conversion, the original object is effectively
00784     // hidden from the pipeline.
00785 
00786     NodeToXref(pNode, filename, false);
00787 
00788     // leave all XRef settings at defaults for this sample
00789 
00790     m_pInterface->RedrawViews(m_pInterface->GetTime());
00791 
00792 }

void Xrefutil::ConvertSelectedToXrefScene ( HWND hWnd )
 

Definition at line 539 of file xrefutil.cpp.

00540 {
00541     // *** ConvertSelectedToXrefScene ***
00542     //
00543     // Relatively simple -- take the selected nodes, save them out
00544     // to a new .MAX file, delete the selected nodes from the 
00545     // current scene, and then do a RootNode->AddNewXRefFile
00546     // with the just-saved MAX file.
00547 
00548     INode * pNode = NULL;
00549     TSTR filename = "";
00550     int i;
00551 
00552     INode * pRootNode = m_pInterface->GetRootNode();
00553     if (!pRootNode) {
00554         // well, this is actually _really_ bad, but we just exit
00555         return;
00556     }
00557     if (m_pInterface->GetSelNodeCount() == 0) {
00558         ::MessageBox(hWnd, GetString(IDS_ERR3), ERROR_TITLE, MB_ICONSTOP | MB_OK);
00559         return;
00560     }
00561 
00562     Tab<INode *> nodetab;
00563     nodetab.ZeroCount();
00564         nodetab.Shrink();
00565     for (i = 0; i < m_pInterface->GetSelNodeCount(); i++) {
00566         pNode = m_pInterface->GetSelNode(i);
00567         nodetab.Append(1, &pNode, 5);
00568     }
00569 
00570     if (!DoOpenSaveDialog(filename)) {
00571         // either cancel or fail, just return
00572         return;
00573     }
00574 
00575     m_pInterface->FileSaveSelected(filename);
00576 
00577     // delete selected nodes, don't refresh yet
00578     for (i = 0; i < nodetab.Count(); i++) {
00579         nodetab[i]->Delete(0,TRUE);
00580     }
00581 
00582     // add in the nodes we saved out as an xref'd scene
00583     pRootNode->AddNewXRefFile(filename, TRUE);
00584     
00585     m_pInterface->RedrawViews(m_pInterface->GetTime());
00586 
00587 }

void Xrefutil::DeleteAllAnimation ( ReferenceTarget * ref )
 

Definition at line 657 of file xrefutil.cpp.

Referenced by AddNewXrefObject().

00658 {
00659     DeleteAllAnimEnum en(TRUE);
00660     ref->EnumAnimTree(&en,NULL,0);
00661 }

void Xrefutil::DeleteThis ( )
 

Definition at line 297 of file xrefutil.cpp.

00298 {
00299     // since there's only one static instance of the
00300     // UtilityObj, we don't do anything here
00301 }

void Xrefutil::Destroy ( HWND hWnd )
 

Definition at line 311 of file xrefutil.cpp.

00312 {
00313 }

bool Xrefutil::DoOpenSaveDialog ( TSTR & fileName,
bool bOpen = false )
 

Definition at line 315 of file xrefutil.cpp.

Referenced by AddNewXrefObject(), AddNewXrefScene(), ConvertSelectedToXrefObject(), and ConvertSelectedToXrefScene().

00316 {
00317 
00318     // Does a standard Win32 CommonDlg Save-As or Open dialog
00319     // for a .MAX file
00320     //
00321     // (doesn't use registered custom dlg in MAX, as
00322     // in truth, only MAX can access this cache currently,
00323     // although you'll get any registered dialog if
00324     // you call Interface::FileSave or something similar,
00325     // but we just want to get a filename, not save yet)
00326 
00327     OPENFILENAME    ofn;
00328     TCHAR           szFilter[]=__TEXT("3D Studio MAX (*.MAX)\0*.MAX\0\0");     
00329     TCHAR           fname[512];
00330 
00331     _tcscpy(fname,fileName);
00332     
00333     // set up that OPENFILENAME struct
00334     ::memset(&ofn, 0, sizeof(OPENFILENAME));
00335     ofn.lStructSize      = sizeof(OPENFILENAME);
00336     ofn.hwndOwner        = m_hPanel;
00337     ofn.nFilterIndex     = 1L;
00338     ofn.lpstrFilter      = szFilter;
00339     ofn.lpstrCustomFilter = (LPTSTR)NULL;
00340     ofn.lpstrFile        = fname;
00341     ofn.nMaxFile         = sizeof(fname) / sizeof(TCHAR);
00342     ofn.lpstrFileTitle   = NULL;
00343     ofn.nMaxFileTitle    = 0;
00344     ofn.lpstrInitialDir  = m_pInterface->GetDir(APP_SCENE_DIR);
00345     ofn.lpstrTitle       = (LPCSTR)NULL;
00346     if (bOpen) {
00347         ofn.Flags            = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_LONGNAMES;
00348     } else {
00349         ofn.Flags            = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_LONGNAMES | OFN_OVERWRITEPROMPT;
00350     }
00351     ofn.lpstrDefExt      = _TEXT("MAX");
00352 
00353     if (bOpen) {
00354         if (GetOpenFileName(&ofn)) {
00355 
00356             // NOTE: More error checking needs to be done for this
00357             // to be practical -- e.g. we shouldn't allow the user to
00358             // select the currently open file.  
00359              
00360             fileName = TSTR(ofn.lpstrFile); // full path and file 
00361             return true; // success
00362 
00363         } else {
00364             // user canceled
00365             return false;
00366         }
00367 
00368     } else {   
00369         if (GetSaveFileName(&ofn)) {
00370 
00371             // NOTE: More error checking needs to be done for this
00372             // to be practical -- e.g. we shouldn't allow the user to
00373             // select the currently open file.  
00374              
00375             fileName = TSTR(ofn.lpstrFile); // full path and file 
00376             return true; // success
00377 
00378         } else {
00379             // user canceled
00380             return false;
00381         }
00382     }
00383     return false; // failure
00384 }

bool Xrefutil::DoPickObjDialog ( )
 

Definition at line 450 of file xrefutil.cpp.

Referenced by AddNewXrefObject().

00451 {
00452     // populate IDD_PICKOBJ IDC_LIST_NODES with objnames,
00453     // show dialog modal, get and return results
00454     int dlgres = 0;
00455     
00456     dlgres = DialogBox(hInstance, 
00457                        MAKEINTRESOURCE(IDD_PICKOBJ),
00458                        m_hPanel,
00459                        PickObjDlgProc);
00460     if (dlgres == 1) return true;
00461     return false; // failure
00462 }

void Xrefutil::EndEditParams ( Interface * ip,
IUtil * iu )
 

Definition at line 289 of file xrefutil.cpp.

00290 {
00291     m_pUtil = NULL;
00292     m_pInterface = NULL;
00293     ip->DeleteRollupPage(m_hPanel);
00294     m_hPanel = NULL;
00295 }

void Xrefutil::ExportXrefObjects ( HWND hWnd )
 

Definition at line 795 of file xrefutil.cpp.

00796 {
00797     // *** ExportXrefObjects ***
00798     //
00799     // Does a "fake" export of all the XRef objects in the scene.
00800     // Basically, walks the scene looking for XRef objects, pulls
00801     // some information from them, and spits this out into a text
00802     // format, which is then displayed in a modal dialog.
00803     //
00804     // In reality, this sort of process would be more applicable
00805     // to a MAX Exporter plug-in. During SceneExport::DoExport
00806     // the INodes would be walked, looking for XRef objects, and
00807     // the exporter could then export whatever was needed from
00808     // them.
00809     //
00810     // The important distinction between XRef scenes and XRef
00811     // objects is again shown here -- XRef objects, to be manipulated
00812     // must be found in the scene via ClassID (like any typical
00813     // scene object), and then treated as IXRefObject pointers.
00814     // Do NOT use the XRef methods off of INode, since these only
00815     // apply to xref scenes and only work from the scene root INode.
00816 
00817     TSTR * resbuffer = NULL;
00818 
00819     // walk the scene starting at the root, looking for xref objects
00820     INode * pRootNode = m_pInterface->GetRootNode();
00821     if (!pRootNode) {
00822         // well, this is actually _really_ bad, but we just exit
00823         return;
00824     }
00825     resbuffer = new TSTR; 
00826     if (!resbuffer) return;
00827 
00828     XRefObjFinder newfinder;
00829     newfinder.m_buffer = resbuffer;
00830     // (see XRefObjFinder::Proc above for details)
00831     newfinder.Enumerate(pRootNode);
00832 
00833     // finally, display results in dialog
00834     int dlgres = DialogBoxParam(hInstance, 
00835                        MAKEINTRESOURCE(IDD_DLGEXPORT),
00836                        m_hPanel,
00837                        ExportDlgProc,
00838                        (LPARAM)resbuffer);
00839 
00840     delete resbuffer;
00841 }

void Xrefutil::Init ( HWND hWnd )
 

Definition at line 307 of file xrefutil.cpp.

00308 {
00309 }

void Xrefutil::MergeAllXrefScenes ( HWND hWnd )
 

Definition at line 616 of file xrefutil.cpp.

00617 {
00618     // *** MergeAllXrefScenes ***
00619     //
00620     // Merges ("binds") all XRef Scenes into the
00621     // current scene.  Just using RootNode::BindXRefFile
00622     // will merge in the real scene objects from the xref'd
00623     // scene as real modifiable objects, and delete the
00624     // xref scene link from the scene hierarchy.
00625 
00626     INode * pNode = NULL;
00627     int i, numxrefscenes;
00628 
00629     INode * pRootNode = m_pInterface->GetRootNode();
00630     if (!pRootNode) {
00631         // well, this is actually _really_ bad, but we just exit
00632         return;
00633     }
00634     numxrefscenes = pRootNode->GetXRefFileCount();
00635     for (i = 0; i < numxrefscenes; i++) {
00636         pRootNode->BindXRefFile(i);
00637     }
00638 
00639 }

void Xrefutil::NodeToXref ( INode * pNode,
TSTR & filename,
bool bProxy,
bool bIgnoreAnim = false )
 

Definition at line 645 of file xrefutil.cpp.

Referenced by AddNewXrefObject(), and ConvertSelectedToXrefObject().

00646 {
00647     IXRefObject * pXRef = (IXRefObject *)m_pInterface->CreateInstance(SYSTEM_CLASS_ID, 
00648         Class_ID(XREFOBJ_CLASS_ID,0));
00649     TSTR obName = TSTR(pNode->GetName());
00650     pXRef->Init(filename, obName, pNode->GetObjectRef(), bProxy);
00651     pNode->SetObjectRef(pXRef);
00652     // also, set visual queue that we're ignoring anim if we did
00653     if (bIgnoreAnim)
00654         pXRef->SetIgnoreAnim(TRUE,FALSE);
00655 }

void Xrefutil::RefreshAllXrefScenes ( HWND hWnd )
 

Definition at line 590 of file xrefutil.cpp.

00591 {
00592     // *** RefreshAllXrefScenes ***
00593     // 
00594     // Refreshes all Xref'd Scenes -- mimics 
00595     // MAX's "Update Now" button on XRef Scene dialog,
00596     // with all xref'd scenes selected.
00597     //
00598     // Simply walk through all XRef'd scenes (hanging off root)
00599     // and use RootNode::ReloadXRef() to reload each one.
00600 
00601     INode * pNode = NULL;
00602     int i, numxrefscenes;
00603 
00604     INode * pRootNode = m_pInterface->GetRootNode();
00605     if (!pRootNode) {
00606         // well, this is actually _really_ bad, but we just exit
00607         return;
00608     }
00609     numxrefscenes = pRootNode->GetXRefFileCount();
00610     for (i = 0; i < numxrefscenes; i++) {
00611         pRootNode->ReloadXRef(i);
00612     }
00613 }


Member Data Documentation

HWND Xrefutil::m_hPanel
 

Definition at line 65 of file xrefutil.h.

bool Xrefutil::m_ignoreanimholder
 

Definition at line 71 of file xrefutil.h.

Tab< TSTR *> Xrefutil::m_objnamesholder
 

Definition at line 68 of file xrefutil.h.

Interface * Xrefutil::m_pInterface
 

Definition at line 64 of file xrefutil.h.

IUtil * Xrefutil::m_pUtil
 

Definition at line 63 of file xrefutil.h.

TSTR Xrefutil::m_picknameholder
 

Definition at line 69 of file xrefutil.h.

bool Xrefutil::m_proxyholder
 

Definition at line 70 of file xrefutil.h.


The documentation for this class was generated from the following files:
Generated at Mon Nov 6 14:11:59 2000 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000