Panda3D
 All Classes Functions Variables Enumerations
maxOptionsDialog.cxx
1 /*
2  maxEggExpOptions.cxx
3  Created by Phillip Saltzman, 2/15/05
4  Carnegie Mellon University, Entetainment Technology Center
5 
6  This file implements the classes that are used to choose
7  what to export from 3D Studio max
8 
9  Updated by Fei Wang, Carnegie Mellon University Entertainment
10  Technology Center student, 14Aug2009: added enableAddCollisionChoices
11 */
12 
13 #include "maxEgg.h"
14 
15 //Disable the forcing int to true or false performance warning
16 #pragma warning(disable: 4800)
17 
18 void SetICustEdit(HWND wnd, int nIDDlgItem, TCHAR *text)
19 {
20  ICustEdit *edit = GetICustEdit(GetDlgItem(wnd, nIDDlgItem));
21  edit->SetText(text);
22  ReleaseICustEdit(edit);
23 }
24 
25 void SetICustEdit(HWND wnd, int nIDDlgItem, int n)
26 {
27  TCHAR text[80];
28  _stprintf(text, _T("%d"), n);
29  ICustEdit *edit = GetICustEdit(GetDlgItem(wnd, nIDDlgItem));
30  edit->SetText(text);
31  ReleaseICustEdit(edit);
32 }
33 
34 TCHAR *GetICustEditT(HWND wnd)
35 {
36  static TCHAR buffer[2084];
37  ICustEdit *edit = GetICustEdit(wnd);
38  edit->GetText(buffer, 2084);
39  ReleaseICustEdit(edit);
40  return buffer;
41 }
42 
43 int GetICustEditI(HWND wnd, BOOL *valid)
44 {
45  ICustEdit *edit = GetICustEdit(wnd);
46  int i = edit->GetInt(valid);
47  ReleaseICustEdit(edit);
48  return i;
49 }
50 
51 void ChunkSave(ISave *isave, int chunkid, int value)
52 {
53  ULONG nb;
54  isave->BeginChunk(chunkid);
55  isave->Write(&value, sizeof(int), &nb);
56  isave->EndChunk();
57 }
58 
59 void ChunkSave(ISave *isave, int chunkid, ULONG value)
60 {
61  ULONG nb;
62  isave->BeginChunk(chunkid);
63  isave->Write(&value, sizeof(ULONG), &nb);
64  isave->EndChunk();
65 }
66 
67 void ChunkSave(ISave *isave, int chunkid, bool value)
68 {
69  ULONG nb;
70  isave->BeginChunk(chunkid);
71  isave->Write(&value, sizeof(bool), &nb);
72  isave->EndChunk();
73 }
74 
75 void ChunkSave(ISave *isave, int chunkid, TCHAR *value)
76 {
77  ULONG nb;
78  isave->BeginChunk(chunkid);
79  int length = _tcslen(value) + 1;
80  isave->Write(&length, sizeof(int), &nb);
81  isave->Write(value, length * sizeof(TCHAR), &nb);
82  isave->EndChunk();
83 }
84 
85 TCHAR *ChunkLoadString(ILoad *iload, TCHAR *buffer, int maxLength)
86 {
87  ULONG nb;
88  int length;
89  IOResult res;
90  res = iload->Read(&length, sizeof(int), &nb);
91  assert(res == IO_OK && length <= maxLength);
92  res = iload->Read(buffer, length * sizeof(TCHAR), &nb);
93  assert(res == IO_OK);
94  return buffer;
95 }
96 
97 int ChunkLoadInt(ILoad *iload)
98 {
99  ULONG nb;
100  int value;
101  IOResult res;
102  res = iload->Read(&value, sizeof(int), &nb);
103  assert(res == IO_OK);
104  return value;
105 }
106 
107 int ChunkLoadULONG(ILoad *iload)
108 {
109  ULONG nb, value;
110  IOResult res;
111  res = iload->Read(&value, sizeof(ULONG), &nb);
112  assert(res == IO_OK);
113  return value;
114 }
115 
116 bool ChunkLoadBool(ILoad *iload)
117 {
118  ULONG nb;
119  bool value;
120  IOResult res;
121  res = iload->Read(&value, sizeof(bool), &nb);
122  assert(res == IO_OK);
123  return value;
124 }
125 
126 void showAnimControls(HWND hWnd, BOOL val) {
127  ShowWindow(GetDlgItem(hWnd, IDC_EF_LABEL), val);
128  ShowWindow(GetDlgItem(hWnd, IDC_EF), val);
129  ShowWindow(GetDlgItem(hWnd, IDC_SF_LABEL), val);
130  SetWindowText(GetDlgItem(hWnd, IDC_EXP_SEL_FRAMES),
131  val ? _T("Use Range:") : _T("Use Frame:"));
132 }
133 
134 void enableAnimControls(HWND hWnd, BOOL val) {
135  EnableWindow(GetDlgItem(hWnd, IDC_SF_LABEL), val);
136  EnableWindow(GetDlgItem(hWnd, IDC_SF), val);
137  EnableWindow(GetDlgItem(hWnd, IDC_EF_LABEL), val);
138  EnableWindow(GetDlgItem(hWnd, IDC_EF), val);
139 }
140 
141 void enableChooserControls(HWND hWnd, BOOL val) {
142  EnableWindow(GetDlgItem(hWnd, IDC_LIST_EXPORT), val);
143  EnableWindow(GetDlgItem(hWnd, IDC_ADD_EXPORT), val);
144  EnableWindow(GetDlgItem(hWnd, IDC_REMOVE_EXPORT), val);
145 }
146 
147 
148 #define ANIM_RAD_NONE 0
149 #define ANIM_RAD_EXPALL 1
150 #define ANIM_RAD_EXPSEL 2
151 #define ANIM_RAD_ALL 3
152 void enableAnimRadios(HWND hWnd, int mask) {
153  EnableWindow(GetDlgItem(hWnd, IDC_EXP_ALL_FRAMES), mask & ANIM_RAD_EXPALL);
154  EnableWindow(GetDlgItem(hWnd, IDC_EXP_SEL_FRAMES), mask & ANIM_RAD_EXPSEL);
155 }
156 
157 // Handles the work of actually picking the target.
158 class AddNodeCB : public HitByNameDlgCallback
159 {
160 public:
161  MaxOptionsDialog *ph; //Pointer to the parent class
162  HWND hWnd; //Handle to the parent dialog
163 
164  AddNodeCB (MaxOptionsDialog *instance, HWND wnd) :
165  ph(instance), hWnd(wnd) {}
166 
167 #if MAX_VERSION_MAJOR < 15
168  virtual TCHAR *dialogTitle() {return _T("Objects to Export");}
169  virtual TCHAR *buttonText() {return _T("Select");}
170 #else
171  virtual const MCHAR *dialogTitle() {return _M("Objects to Export");}
172  virtual const MCHAR *buttonText() {return _M("Select");}
173 #endif
174 
175  virtual int filter(INode *node);
176  virtual void proc(INodeTab &nodeTab);
177 };
178 
179 //This tells what should be in the list
180 //Allow only triangular objects, nurbs, and joints
181 int AddNodeCB::filter(INode *node) {
182  if (!node) return 0;
183 
184  Object *obj = node->EvalWorldState(0).obj;
185  Control *c = node->GetTMController();
186  NURBSSet getSet;
187  bool is_bone = (node->GetBoneNodeOnOff() || //True for bones
188  (c && //True for bipeds
189  ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
190  (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
191  (c->ClassID() == FOOTPRINT_CLASS_ID))));
192 
193 
194  if (IsDlgButtonChecked(hWnd, IDC_ANIMATION) == BST_CHECKED)
195  return is_bone && !ph->FindNode(node->GetHandle());
196  else
197  return (
198  is_bone || ((obj->SuperClassID() == HELPER_CLASS_ID && obj->ClassID() != MaxEggPlugin_CLASS_ID)) ||
199  ((obj->SuperClassID() == GEOMOBJECT_CLASS_ID && //Allow geometrics
200  obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) ||
201  (obj->SuperClassID() == SHAPE_CLASS_ID && //Allow CV NURBS
202  obj->ClassID() == EDITABLE_SURF_CLASS_ID &&
203  GetNURBSSet(obj, 0, getSet, TRUE) &&
204  getSet.GetNURBSObject(0)->GetType() == kNCVCurve)) &&
205  !ph->FindNode(node->GetHandle())); //Only allow items not already selected
206 }
207 
208 //Adds all of the selected items to the list
209 void AddNodeCB::proc(INodeTab &nodeTab) {
210 
211  for (int i = 0; i < nodeTab.Count(); i++)
212  ph->AddNode(nodeTab[i]->GetHandle());
213  ph->RefreshNodeList(hWnd);
214 }
215 
216 //This callback class generates a list of nodes that have previously been selected
217 class RemoveNodeCB : public HitByNameDlgCallback
218 {
219 public:
220  MaxOptionsDialog *ph; //Pointer to the parent class
221  HWND hWnd; //Handle to the parent dialog
222 
223  RemoveNodeCB (MaxOptionsDialog *instance, HWND wnd) :
224  ph(instance), hWnd(wnd) {}
225 
226 #if MAX_VERSION_MAJOR < 15
227  virtual TCHAR *dialogTitle() {return _T("Objects to Remove");}
228  virtual TCHAR *buttonText() {return _T("Remove");}
229 #else
230  virtual const MCHAR *dialogTitle() {return _M("Objects to Remove");}
231  virtual const MCHAR *buttonText() {return _M("Remove");}
232 #endif
233 
234  virtual int filter(INode *node) {return (node && ph->FindNode(node->GetHandle()));}
235  virtual void proc(INodeTab &nodeTab);
236 };
237 
238 
239 //Adds all of the selected items to the list
240 void RemoveNodeCB::proc(INodeTab &nodeTab) {
241  for (int i = 0; i < nodeTab.Count(); i++)
242  ph->RemoveNodeByHandle(nodeTab[i]->GetHandle());
243  ph->RefreshNodeList(hWnd);
244 }
245 
246 MaxEggOptions::MaxEggOptions() {
247  _max_interface = NULL;
248  _anim_type = MaxEggOptions::AT_model;
249  _start_frame = INT_MIN;
250  _end_frame = INT_MIN;
251  _double_sided = false;
252 
253 
254  _file_name[0]=0;
255  _short_name[0]=0;
256  _path_replace = new PathReplace;
257  _path_replace->_path_store = PS_relative;
258  _export_whole_scene = true;
259  _export_all_frames = true;
260  _successful = false;
261 }
262 
263 INT_PTR CALLBACK MaxOptionsDialogProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
264 {
265  TCHAR tempFilename[2048];
266  //We pass in our plugin through the lParam variable. Let's convert it back.
267  MaxOptionsDialog *imp = (MaxOptionsDialog*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
268  if ( !imp && message != WM_INITDIALOG ) return FALSE;
269 
270  switch(message) {
271 
272  case WM_INITDIALOG:
273  // this line is very necessary to pass the plugin as the lParam
274  SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam);
275  ((MaxOptionsDialog*)lParam)->UpdateUI(hWnd);
276 
277  return TRUE; break;
278 
279  case WM_CLOSE:
280  EndDialog(hWnd, FALSE);
281  return TRUE; break;
282 
283  case WM_COMMAND:
284  //The modified control is found in the lower word of the wParam long.
285  switch( LOWORD(wParam) ) {
286  case IDC_MODEL:
287  if (HIWORD(wParam) == BN_CLICKED) {
288  SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
289  _T("Export Meshes:"));
290  enableAnimRadios(hWnd, ANIM_RAD_NONE);
291  showAnimControls(hWnd, TRUE);
292  enableAnimControls(hWnd, FALSE);
293  if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
294  imp->_prev_type = MaxEggOptions::AT_model;
295 
296  return TRUE;
297  }
298  break;
299 
300  case IDC_ANIMATION:
301  if (HIWORD(wParam) == BN_CLICKED) {
302  SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
303  _T("Export Bones:"));
304  enableAnimRadios(hWnd, ANIM_RAD_ALL);
305  showAnimControls(hWnd, TRUE);
306  enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES));
307  if (imp->_prev_type != MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
308  imp->_prev_type = MaxEggOptions::AT_chan;
309  CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_ALL_FRAMES);
310 
311  return TRUE;
312  }
313  break;
314  case IDC_BOTH:
315  if (HIWORD(wParam) == BN_CLICKED) {
316  SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
317  _T("Export Models:"));
318  enableAnimRadios(hWnd, ANIM_RAD_ALL);
319  showAnimControls(hWnd, TRUE);
320  enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES));
321  if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
322  imp->_prev_type = MaxEggOptions::AT_both;
323  CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_ALL_FRAMES);
324 
325  return TRUE;
326  }
327  break;
328  case IDC_POSE:
329  if (HIWORD(wParam) == BN_CLICKED) {
330  SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
331  _T("Export Meshes:"));
332  enableAnimRadios(hWnd, ANIM_RAD_EXPSEL);
333  showAnimControls(hWnd, FALSE);
334  enableAnimControls(hWnd, TRUE);
335  CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_SEL_FRAMES);
336  if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
337  imp->_prev_type = MaxEggOptions::AT_pose;
338 
339  return TRUE;
340  }
341  break;
342  case IDC_EXP_ALL_FRAMES:
343  if (HIWORD(wParam) == BN_CLICKED) {
344  enableAnimControls(hWnd, FALSE);
345  if(imp->_prev_type == MaxEggOptions::AT_chan)
346  {
347  CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_ANIMATION);
348  }
349  if(imp->_prev_type == MaxEggOptions::AT_both)
350  {
351  CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_BOTH);
352  }
353  return TRUE;
354  }
355  break;
356 
357  case IDC_EXP_SEL_FRAMES:
358  if (HIWORD(wParam) == BN_CLICKED) {
359  enableAnimControls(hWnd, TRUE);
360  if(imp->_prev_type == MaxEggOptions::AT_chan)
361  {
362  CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_ANIMATION);
363  }
364  if(imp->_prev_type == MaxEggOptions::AT_both)
365  {
366  CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_BOTH);
367  }
368  return TRUE;
369  }
370  break;
371 
372  case IDC_EXPORT_ALL:
373  if (HIWORD(wParam) == BN_CLICKED) {
374  enableChooserControls(hWnd, FALSE);
375  return TRUE;
376  }
377  break;
378 
379  case IDC_EXPORT_SELECTED:
380  if (HIWORD(wParam) == BN_CLICKED) {
381  enableChooserControls(hWnd, TRUE);
382  return TRUE;
383  }
384  break;
385 
386 
387  // deal with adding meshes
388  case IDC_ADD_EXPORT:
389  {
390  if (!imp->_choosing_nodes) {
391  AddNodeCB PickCB(imp, hWnd);
392  imp->_choosing_nodes = true;
393  imp->_max_interface->DoHitByNameDialog(&PickCB);
394  imp->_choosing_nodes = false;
395  }
396  }
397  return TRUE; break;
398 
399  case IDC_REMOVE_EXPORT:
400  {
401  if (!imp->_choosing_nodes) {
402  imp->_choosing_nodes = true;
403  RemoveNodeCB PickCB(imp, hWnd);
404  imp->_max_interface->DoHitByNameDialog(&PickCB);
405  imp->_choosing_nodes = false;
406  }
407  }
408  return TRUE; break;
409 
410  case IDC_OK:
411  if (imp->UpdateFromUI(hWnd)) EndDialog(hWnd, TRUE);
412  return TRUE; break;
413  case IDC_CANCEL:
414  EndDialog(hWnd, FALSE);
415  return TRUE; break;
416  case IDC_BROWSE:
417  OPENFILENAME ofn;
418  _tcscpy(tempFilename, GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME)));
419 
420  memset(&ofn, 0, sizeof(ofn));
421  ofn.nMaxFile = 2047;
422  ofn.lpstrFile = tempFilename;
423  ofn.lStructSize = sizeof(ofn);
424  ofn.hwndOwner = hWnd;
425  ofn.Flags = OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST;
426  ofn.lpstrDefExt = _T("egg");
427  ofn.lpstrFilter = _T("Panda3D Egg Files (*.egg)\0*.egg\0All Files (*.*)\0*.*\0");
428 
429  SetFocus(GetDlgItem(hWnd, IDC_FILENAME));
430  if (GetSaveFileName(&ofn))
431  SetICustEdit(hWnd, IDC_FILENAME, ofn.lpstrFile);
432  //else {
433  // char buf[255];
434  // sprintf(buf, "%d", CommDlgExtendedError());
435  // MessageBox(hWnd, buf, "Error on GetSaveFileName", MB_OK);
436  //}
437  return TRUE; break;
438  case IDC_CHECK1:
439  if (IsDlgButtonChecked(hWnd, IDC_CHECK1))
440  if (MessageBox(hWnd, _T("Warning: Exporting double-sided polygons can severely hurt ")
441  _T("performance in Panda3D.\n\nAre you sure you want to export them?"),
442  _T("Panda3D Exporter"), MB_YESNO | MB_ICONQUESTION) != IDYES)
443  CheckDlgButton(hWnd, IDC_CHECK1, BST_UNCHECKED);
444  return TRUE; break;
445 
446  default:
447  //char buf[255];
448  //sprintf(buf, "%d", LOWORD(wParam));
449  //MessageBox(hWnd, buf, "Unknown WParam", MB_OK);
450  break;
451  }
452  }
453  return FALSE;
454 }
455 
456 void MaxOptionsDialog::SetAnimRange() {
457  // Get the start and end frames and the animation frame rate from Max
458  Interval anim_range = _max_interface->GetAnimRange();
459  _min_frame = anim_range.Start()/GetTicksPerFrame();
460  _max_frame = anim_range.End()/GetTicksPerFrame();
461 }
462 
463 MaxOptionsDialog::MaxOptionsDialog() :
464  MaxEggOptions(),
465  _min_frame(0),
466  _max_frame(0),
467  _checked(true),
468  _choosing_nodes(false),
469  _prev_type(AT_model)
470 {
471 }
472 
473 MaxOptionsDialog::~MaxOptionsDialog ()
474 {
475 }
476 
477 
478 void MaxOptionsDialog::UpdateUI(HWND hWnd) {
479  int typeButton = IDC_MODEL;
480  int anim_exp = _export_all_frames ? IDC_EXP_ALL_FRAMES : IDC_EXP_SEL_FRAMES;
481  int model_exp = _export_whole_scene ? IDC_EXPORT_ALL : IDC_EXPORT_SELECTED;
482 
483  switch (_anim_type) {
484  case MaxEggOptions::AT_chan: typeButton = IDC_ANIMATION; break;
485  case MaxEggOptions::AT_both: typeButton = IDC_BOTH; break;
486  case MaxEggOptions::AT_pose: typeButton = IDC_POSE; break;
487  case MaxEggOptions::AT_model: typeButton = IDC_MODEL; break;
488  }
489 
490  _prev_type = _anim_type;
491 
492  CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, typeButton);
493  SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(typeButton, BN_CLICKED), 0);
494  CheckRadioButton(hWnd, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, model_exp);
495  SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(model_exp, BN_CLICKED), 0);
496  CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, anim_exp);
497  SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(anim_exp, BN_CLICKED), 0);
498 
499  CheckDlgButton(hWnd, IDC_CHECK1,
500  _double_sided ? BST_CHECKED : BST_UNCHECKED);
501 
502 
503  SetICustEdit(hWnd, IDC_FILENAME, _file_name);
504  if (_start_frame != INT_MIN) {
505  SetICustEdit(hWnd, IDC_SF, _start_frame);
506  SetICustEdit(hWnd, IDC_EF, _end_frame);
507  } else {
508  SetICustEdit(hWnd, IDC_SF, _min_frame);
509  SetICustEdit(hWnd, IDC_EF, _max_frame);
510  }
511 
512  RefreshNodeList(hWnd);
513 }
514 
515 void MaxOptionsDialog::ClearNodeList(HWND hWnd) {
516  _node_list.clear();
517  RefreshNodeList(hWnd);
518 }
519 
520 void MaxOptionsDialog::RefreshNodeList(HWND hWnd) {
521  //Clear and repopulate the node box
522  HWND nodeLB = GetDlgItem(hWnd, IDC_LIST_EXPORT);
523  SendMessage(nodeLB, LB_RESETCONTENT, 0, 0);
524  for (int i = 0; i < _node_list.size(); i++) {
525  INode *temp = _max_interface->GetINodeByHandle(_node_list[i]);
526  const TCHAR *name = _T("Unknown Node");
527  if (temp) name = temp->GetName();
528  SendMessage(nodeLB, LB_ADDSTRING, 0, (LPARAM)name);
529  }
530 }
531 
532 bool MaxOptionsDialog::UpdateFromUI(HWND hWnd) {
533  BOOL valid;
534  Anim_Type newAnimType;
535  int newSF = INT_MIN, newEF = INT_MIN;
536  TCHAR msg[1024];
537 
538  if (IsDlgButtonChecked(hWnd, IDC_MODEL)) newAnimType = MaxEggOptions::AT_model;
539  else if (IsDlgButtonChecked(hWnd, IDC_ANIMATION)) newAnimType = MaxEggOptions::AT_chan;
540  else if (IsDlgButtonChecked(hWnd, IDC_BOTH)) newAnimType = MaxEggOptions::AT_both;
541  else newAnimType = MaxEggOptions::AT_pose;
542 
543  if (newAnimType != MaxEggOptions::AT_model && IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES)) {
544  newSF = GetICustEditI(GetDlgItem(hWnd, IDC_SF), &valid);
545  if (!valid) {
546  MessageBox(hWnd, _T("Start Frame must be an integer"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
547  return false;
548  }
549  if (newSF < _min_frame) {
550  _stprintf(msg, _T("Start Frame must be at least %d"), _min_frame);
551  MessageBox(hWnd, msg, _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
552  return false;
553  }
554  if (newSF > _max_frame) {
555  _stprintf(msg, _T("Start Frame must be at most %d"), _max_frame);
556  MessageBox(hWnd, msg, _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
557  return false;
558  }
559  if (newAnimType != MaxEggOptions::AT_pose) {
560  newEF = GetICustEditI(GetDlgItem(hWnd, IDC_EF), &valid);
561  if (!valid) {
562  MessageBox(hWnd, _T("End Frame must be an integer"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
563  return false;
564  }
565  if (newEF > _max_frame) {
566  _stprintf(msg, _T("End Frame must be at most %d"), _max_frame);
567  MessageBox(hWnd, msg, _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
568  return false;
569  }
570  if (newEF < newSF) {
571  MessageBox(hWnd, _T("End Frame must be greater than the start frame"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
572  return false;
573  }
574  }
575  }
576 
577  TCHAR *temp = GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME));
578  if (!_tcslen(temp)) {
579  MessageBox(hWnd, _T("The filename cannot be empty"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
580  return false;
581  }
582 
583  if (_tcslen(temp) < 4 || _tcsncmp(_T(".egg"), temp+(_tcslen(temp) - 4), 4)) {
584  _stprintf(_file_name, _T("%s.egg"), temp);
585  } else {
586  _tcscpy(_file_name, temp);
587  }
588 
589  temp = _tcsrchr(_file_name, '\\');
590  if (!temp) temp = _file_name;
591  else temp++;
592 
593  if (_tcslen(temp) > sizeof(_short_name))
594  _stprintf(_short_name, _T("%.*s..."), sizeof(_short_name)-4, temp);
595  else {
596  _tcscpy(_short_name, temp);
597  _short_name[_tcslen(_short_name) - 4] = NULL; //Cut off the .egg
598  }
599 
600  _start_frame = newSF;
601  _end_frame = newEF;
602  _anim_type = newAnimType;
603  _double_sided = IsDlgButtonChecked(hWnd, IDC_CHECK1);
604 
605 
606  _export_whole_scene = IsDlgButtonChecked(hWnd, IDC_EXPORT_ALL);
607  _export_all_frames = IsDlgButtonChecked(hWnd, IDC_EXP_ALL_FRAMES);
608 
609  return true;
610 }
611 
612 bool MaxOptionsDialog::FindNode(ULONG INodeHandle) {
613  for (int i = 0; i < _node_list.size(); i++)
614  if (_node_list[i] == INodeHandle) return true;
615  return false;
616 }
617 
618 void MaxOptionsDialog::AddNode(ULONG INodeHandle) {
619  if (FindNode(INodeHandle)) return;
620  _node_list.push_back(INodeHandle);
621 }
622 
623 void MaxOptionsDialog::CullBadNodes() {
624  if (!_max_interface) return;
625  std::vector<ULONG> good;
626  for (int i=0; i<_node_list.size(); i++) {
627  ULONG handle = _node_list[i];
628  if (_max_interface->GetINodeByHandle(handle)) {
629  good.push_back(handle);
630  }
631  }
632  _node_list = good;
633 }
634 
635 void MaxOptionsDialog::RemoveNode(int i) {
636  if (i >= 0 && i < _node_list.size()) {
637  for (int j = i+1; j < _node_list.size(); j++)
638  _node_list[i++] = _node_list[j++];
639  _node_list.pop_back();
640  }
641 }
642 
643 void MaxOptionsDialog::RemoveNodeByHandle(ULONG INodeHandle) {
644  for (int i = 0; i < _node_list.size(); i++) {
645  if (_node_list[i] == INodeHandle) {
646  RemoveNode(i);
647  return;
648  }
649  }
650 }
651 
652 IOResult MaxOptionsDialog::Save(ISave *isave) {
653  isave->BeginChunk(CHUNK_EGG_EXP_OPTIONS);
654  ChunkSave(isave, CHUNK_ANIM_TYPE, _anim_type);
655  ChunkSave(isave, CHUNK_FILENAME, _file_name);
656  ChunkSave(isave, CHUNK_SHORTNAME, _short_name);
657  ChunkSave(isave, CHUNK_SF, _start_frame);
658  ChunkSave(isave, CHUNK_EF, _end_frame);
659  ChunkSave(isave, CHUNK_DBL_SIDED, _double_sided);
660  ChunkSave(isave, CHUNK_EGG_CHECKED, _checked);
661  ChunkSave(isave, CHUNK_ALL_FRAMES, _export_all_frames);
662  ChunkSave(isave, CHUNK_EXPORT_FULL, _export_whole_scene);
663 
664  isave->BeginChunk(CHUNK_NODE_LIST);
665  for (int i = 0; i < _node_list.size(); i++)
666  ChunkSave(isave, CHUNK_NODE_HANDLE, _node_list[i]);
667  isave->EndChunk();
668  isave->EndChunk();
669  return IO_OK;
670 }
671 
672 IOResult MaxOptionsDialog::Load(ILoad *iload) {
673  IOResult res = iload->OpenChunk();
674 
675  while (res == IO_OK) {
676  switch(iload->CurChunkID()) {
677  case CHUNK_ANIM_TYPE: _anim_type = (Anim_Type)ChunkLoadInt(iload); break;
678  case CHUNK_FILENAME: ChunkLoadString(iload, _file_name, sizeof(_file_name)); break;
679  case CHUNK_SHORTNAME: ChunkLoadString(iload, _short_name, sizeof(_short_name)); break;
680  case CHUNK_SF: _start_frame = ChunkLoadInt(iload); break;
681  case CHUNK_EF: _end_frame = ChunkLoadInt(iload); break;
682  case CHUNK_DBL_SIDED: _double_sided = ChunkLoadBool(iload); break;
683  case CHUNK_EGG_CHECKED: _checked = ChunkLoadBool(iload); break;
684  case CHUNK_ALL_FRAMES: _export_all_frames = ChunkLoadBool(iload); break;
685  case CHUNK_EXPORT_FULL: _export_whole_scene = ChunkLoadBool(iload); break;
686 
687  case CHUNK_NODE_LIST:
688  res = iload->OpenChunk();
689  while (res == IO_OK) {
690  if (iload->CurChunkID() == CHUNK_NODE_HANDLE) AddNode(ChunkLoadULONG(iload));
691  iload->CloseChunk();
692  res = iload->OpenChunk();
693  }
694  break;
695  }
696  iload->CloseChunk();
697  res = iload->OpenChunk();
698  }
699 
700  if (res == IO_END) return IO_OK;
701  return IO_ERROR;
702 }
703 
This encapsulates the user&#39;s command-line request to replace existing, incorrect pathnames to models ...
Definition: pathReplace.h:40