Panda3D

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 Allow only triangular objects, nurbs,
180 // 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
217 // selected
218 class RemoveNodeCB : public HitByNameDlgCallback
219 {
220 public:
221 MaxOptionsDialog *ph; //Pointer to the parent class
222 HWND hWnd; //Handle to the parent dialog
223
224 RemoveNodeCB (MaxOptionsDialog *instance, HWND wnd) :
225 ph(instance), hWnd(wnd) {}
226
227 #if MAX_VERSION_MAJOR < 15
228 virtual TCHAR *dialogTitle() {return _T("Objects to Remove");}
229 virtual TCHAR *buttonText() {return _T("Remove");}
230 #else
231 virtual const MCHAR *dialogTitle() {return _M("Objects to Remove");}
232 virtual const MCHAR *buttonText() {return _M("Remove");}
233 #endif
234
235 virtual int filter(INode *node) {return (node && ph->FindNode(node->GetHandle()));}
236 virtual void proc(INodeTab &nodeTab);
237 };
238
239
240 // Adds all of the selected items to the list
241 void RemoveNodeCB::proc(INodeTab &nodeTab) {
242 for (int i = 0; i < nodeTab.Count(); i++)
243 ph->RemoveNodeByHandle(nodeTab[i]->GetHandle());
244 ph->RefreshNodeList(hWnd);
245 }
246
247 MaxEggOptions::MaxEggOptions() {
248 _max_interface = nullptr;
249 _anim_type = MaxEggOptions::AT_model;
250 _start_frame = INT_MIN;
251 _end_frame = INT_MIN;
252 _double_sided = false;
253
254
255 _file_name[0]=0;
256 _short_name[0]=0;
257 _path_replace = new PathReplace;
258 _path_replace->_path_store = PS_relative;
259 _export_whole_scene = true;
260 _export_all_frames = true;
261 _successful = false;
262 }
263
264 INT_PTR CALLBACK MaxOptionsDialogProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
265 {
266 TCHAR tempFilename[2048];
267 // We pass in our plugin through the lParam variable. Let's convert it
268 // back.
269 MaxOptionsDialog *imp = (MaxOptionsDialog*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
270 if ( !imp && message != WM_INITDIALOG ) return FALSE;
271
272 switch(message) {
273
274 case WM_INITDIALOG:
275 // this line is very necessary to pass the plugin as the lParam
276 SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam);
277 ((MaxOptionsDialog*)lParam)->UpdateUI(hWnd);
278
279 return TRUE; break;
280
281 case WM_CLOSE:
282 EndDialog(hWnd, FALSE);
283 return TRUE; break;
284
285 case WM_COMMAND:
286 // The modified control is found in the lower word of the wParam long.
287 switch( LOWORD(wParam) ) {
288 case IDC_MODEL:
289 if (HIWORD(wParam) == BN_CLICKED) {
290 SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
291 _T("Export Meshes:"));
292 enableAnimRadios(hWnd, ANIM_RAD_NONE);
293 showAnimControls(hWnd, TRUE);
294 enableAnimControls(hWnd, FALSE);
295 if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
296 imp->_prev_type = MaxEggOptions::AT_model;
297
298 return TRUE;
299 }
300 break;
301
302 case IDC_ANIMATION:
303 if (HIWORD(wParam) == BN_CLICKED) {
304 SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
305 _T("Export Bones:"));
306 enableAnimRadios(hWnd, ANIM_RAD_ALL);
307 showAnimControls(hWnd, TRUE);
308 enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES));
309 if (imp->_prev_type != MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
310 imp->_prev_type = MaxEggOptions::AT_chan;
311 CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_ALL_FRAMES);
312
313 return TRUE;
314 }
315 break;
316 case IDC_BOTH:
317 if (HIWORD(wParam) == BN_CLICKED) {
318 SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
319 _T("Export Models:"));
320 enableAnimRadios(hWnd, ANIM_RAD_ALL);
321 showAnimControls(hWnd, TRUE);
322 enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES));
323 if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
324 imp->_prev_type = MaxEggOptions::AT_both;
325 CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_ALL_FRAMES);
326
327 return TRUE;
328 }
329 break;
330 case IDC_POSE:
331 if (HIWORD(wParam) == BN_CLICKED) {
332 SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED),
333 _T("Export Meshes:"));
334 enableAnimRadios(hWnd, ANIM_RAD_EXPSEL);
335 showAnimControls(hWnd, FALSE);
336 enableAnimControls(hWnd, TRUE);
337 CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_SEL_FRAMES);
338 if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd);
339 imp->_prev_type = MaxEggOptions::AT_pose;
340
341 return TRUE;
342 }
343 break;
344 case IDC_EXP_ALL_FRAMES:
345 if (HIWORD(wParam) == BN_CLICKED) {
346 enableAnimControls(hWnd, FALSE);
347 if(imp->_prev_type == MaxEggOptions::AT_chan)
348 {
349 CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_ANIMATION);
350 }
351 if(imp->_prev_type == MaxEggOptions::AT_both)
352 {
353 CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_BOTH);
354 }
355 return TRUE;
356 }
357 break;
358
359 case IDC_EXP_SEL_FRAMES:
360 if (HIWORD(wParam) == BN_CLICKED) {
361 enableAnimControls(hWnd, TRUE);
362 if(imp->_prev_type == MaxEggOptions::AT_chan)
363 {
364 CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_ANIMATION);
365 }
366 if(imp->_prev_type == MaxEggOptions::AT_both)
367 {
368 CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_BOTH);
369 }
370 return TRUE;
371 }
372 break;
373
374 case IDC_EXPORT_ALL:
375 if (HIWORD(wParam) == BN_CLICKED) {
376 enableChooserControls(hWnd, FALSE);
377 return TRUE;
378 }
379 break;
380
381 case IDC_EXPORT_SELECTED:
382 if (HIWORD(wParam) == BN_CLICKED) {
383 enableChooserControls(hWnd, TRUE);
384 return TRUE;
385 }
386 break;
387
388
389 // deal with adding meshes
390 case IDC_ADD_EXPORT:
391 {
392 if (!imp->_choosing_nodes) {
393 AddNodeCB PickCB(imp, hWnd);
394 imp->_choosing_nodes = true;
395 imp->_max_interface->DoHitByNameDialog(&PickCB);
396 imp->_choosing_nodes = false;
397 }
398 }
399 return TRUE; break;
400
401 case IDC_REMOVE_EXPORT:
402 {
403 if (!imp->_choosing_nodes) {
404 imp->_choosing_nodes = true;
405 RemoveNodeCB PickCB(imp, hWnd);
406 imp->_max_interface->DoHitByNameDialog(&PickCB);
407 imp->_choosing_nodes = false;
408 }
409 }
410 return TRUE; break;
411
412 case IDC_OK:
413 if (imp->UpdateFromUI(hWnd)) EndDialog(hWnd, TRUE);
414 return TRUE; break;
415 case IDC_CANCEL:
416 EndDialog(hWnd, FALSE);
417 return TRUE; break;
418 case IDC_BROWSE:
419 OPENFILENAME ofn;
420 _tcscpy(tempFilename, GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME)));
421
422 memset(&ofn, 0, sizeof(ofn));
423 ofn.nMaxFile = 2047;
424 ofn.lpstrFile = tempFilename;
425 ofn.lStructSize = sizeof(ofn);
426 ofn.hwndOwner = hWnd;
427 ofn.Flags = OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST;
428 ofn.lpstrDefExt = _T("egg");
429 ofn.lpstrFilter = _T("Panda3D Egg Files (*.egg)\0*.egg\0All Files (*.*)\0*.*\0");
430
431 SetFocus(GetDlgItem(hWnd, IDC_FILENAME));
432 if (GetSaveFileName(&ofn))
433 SetICustEdit(hWnd, IDC_FILENAME, ofn.lpstrFile);
434 // else { char buf[255]; sprintf(buf, "%d",
435 // CommDlgExtendedError()); MessageBox(hWnd, buf, "Error on
436 // GetSaveFileName", MB_OK); }
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]; sprintf(buf, "%d", LOWORD(wParam));
448 // MessageBox(hWnd, buf, "Unknown WParam", MB_OK);
449 break;
450 }
451 }
452 return FALSE;
453 }
454
455 void MaxOptionsDialog::SetAnimRange() {
456 // Get the start and end frames and the animation frame rate from Max
457 Interval anim_range = _max_interface->GetAnimRange();
458 _min_frame = anim_range.Start()/GetTicksPerFrame();
459 _max_frame = anim_range.End()/GetTicksPerFrame();
460 }
461
462 MaxOptionsDialog::MaxOptionsDialog() :
463 MaxEggOptions(),
464 _min_frame(0),
465 _max_frame(0),
466 _checked(true),
467 _choosing_nodes(false),
468 _prev_type(AT_model)
469 {
470 }
471
472 MaxOptionsDialog::~MaxOptionsDialog ()
473 {
474 }
475
476
477 void MaxOptionsDialog::UpdateUI(HWND hWnd) {
478 int typeButton = IDC_MODEL;
479 int anim_exp = _export_all_frames ? IDC_EXP_ALL_FRAMES : IDC_EXP_SEL_FRAMES;
480 int model_exp = _export_whole_scene ? IDC_EXPORT_ALL : IDC_EXPORT_SELECTED;
481
482 switch (_anim_type) {
483 case MaxEggOptions::AT_chan: typeButton = IDC_ANIMATION; break;
484 case MaxEggOptions::AT_both: typeButton = IDC_BOTH; break;
485 case MaxEggOptions::AT_pose: typeButton = IDC_POSE; break;
486 case MaxEggOptions::AT_model: typeButton = IDC_MODEL; break;
487 }
488
489 _prev_type = _anim_type;
490
491 CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, typeButton);
492 SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(typeButton, BN_CLICKED), 0);
493 CheckRadioButton(hWnd, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, model_exp);
494 SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(model_exp, BN_CLICKED), 0);
495 CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, anim_exp);
496 SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(anim_exp, BN_CLICKED), 0);
497
498 CheckDlgButton(hWnd, IDC_CHECK1,
499 _double_sided ? BST_CHECKED : BST_UNCHECKED);
500
501
502 SetICustEdit(hWnd, IDC_FILENAME, _file_name);
503 if (_start_frame != INT_MIN) {
504 SetICustEdit(hWnd, IDC_SF, _start_frame);
505 SetICustEdit(hWnd, IDC_EF, _end_frame);
506 } else {
507 SetICustEdit(hWnd, IDC_SF, _min_frame);
508 SetICustEdit(hWnd, IDC_EF, _max_frame);
509 }
510
511 RefreshNodeList(hWnd);
512 }
513
514 void MaxOptionsDialog::ClearNodeList(HWND hWnd) {
515 _node_list.clear();
516 RefreshNodeList(hWnd);
517 }
518
519 void MaxOptionsDialog::RefreshNodeList(HWND hWnd) {
520 // Clear and repopulate the node box
521 HWND nodeLB = GetDlgItem(hWnd, IDC_LIST_EXPORT);
522 SendMessage(nodeLB, LB_RESETCONTENT, 0, 0);
523 for (int i = 0; i < _node_list.size(); i++) {
524 INode *temp = _max_interface->GetINodeByHandle(_node_list[i]);
525 const TCHAR *name = _T("Unknown Node");
526 if (temp) name = temp->GetName();
527 SendMessage(nodeLB, LB_ADDSTRING, 0, (LPARAM)name);
528 }
529 }
530
531 bool MaxOptionsDialog::UpdateFromUI(HWND hWnd) {
532 BOOL valid;
533 Anim_Type newAnimType;
534 int newSF = INT_MIN, newEF = INT_MIN;
535 TCHAR msg[1024];
536
537 if (IsDlgButtonChecked(hWnd, IDC_MODEL)) newAnimType = MaxEggOptions::AT_model;
538 else if (IsDlgButtonChecked(hWnd, IDC_ANIMATION)) newAnimType = MaxEggOptions::AT_chan;
539 else if (IsDlgButtonChecked(hWnd, IDC_BOTH)) newAnimType = MaxEggOptions::AT_both;
540 else newAnimType = MaxEggOptions::AT_pose;
541
542 if (newAnimType != MaxEggOptions::AT_model && IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES)) {
543 newSF = GetICustEditI(GetDlgItem(hWnd, IDC_SF), &valid);
544 if (!valid) {
545 MessageBox(hWnd, _T("Start Frame must be an integer"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
546 return false;
547 }
548 if (newSF < _min_frame) {
549 _stprintf(msg, _T("Start Frame must be at least %d"), _min_frame);
550 MessageBox(hWnd, msg, _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
551 return false;
552 }
553 if (newSF > _max_frame) {
554 _stprintf(msg, _T("Start Frame must be at most %d"), _max_frame);
555 MessageBox(hWnd, msg, _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
556 return false;
557 }
558 if (newAnimType != MaxEggOptions::AT_pose) {
559 newEF = GetICustEditI(GetDlgItem(hWnd, IDC_EF), &valid);
560 if (!valid) {
561 MessageBox(hWnd, _T("End Frame must be an integer"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
562 return false;
563 }
564 if (newEF > _max_frame) {
565 _stprintf(msg, _T("End Frame must be at most %d"), _max_frame);
566 MessageBox(hWnd, msg, _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
567 return false;
568 }
569 if (newEF < newSF) {
570 MessageBox(hWnd, _T("End Frame must be greater than the start frame"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
571 return false;
572 }
573 }
574 }
575
576 TCHAR *temp = GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME));
577 if (!_tcslen(temp)) {
578 MessageBox(hWnd, _T("The filename cannot be empty"), _T("Invalid Value"), MB_OK | MB_ICONEXCLAMATION);
579 return false;
580 }
581
582 if (_tcslen(temp) < 4 || _tcsncmp(_T(".egg"), temp+(_tcslen(temp) - 4), 4)) {
583 _stprintf(_file_name, _T("%s.egg"), temp);
584 } else {
585 _tcscpy(_file_name, temp);
586 }
587
588 temp = _tcsrchr(_file_name, '\\');
589 if (!temp) temp = _file_name;
590 else temp++;
591
592 if (_tcslen(temp) > sizeof(_short_name))
593 _stprintf(_short_name, _T("%.*s..."), sizeof(_short_name)-4, temp);
594 else {
595 _tcscpy(_short_name, temp);
596 _short_name[_tcslen(_short_name) - 4] = 0; //Cut off the .egg
597 }
598
599 _start_frame = newSF;
600 _end_frame = newEF;
601 _anim_type = newAnimType;
602 _double_sided = IsDlgButtonChecked(hWnd, IDC_CHECK1);
603
604
605 _export_whole_scene = IsDlgButtonChecked(hWnd, IDC_EXPORT_ALL);
606 _export_all_frames = IsDlgButtonChecked(hWnd, IDC_EXP_ALL_FRAMES);
607
608 return true;
609 }
610
611 bool MaxOptionsDialog::FindNode(ULONG INodeHandle) {
612 for (int i = 0; i < _node_list.size(); i++)
613 if (_node_list[i] == INodeHandle) return true;
614 return false;
615 }
616
617 void MaxOptionsDialog::AddNode(ULONG INodeHandle) {
618 if (FindNode(INodeHandle)) return;
619 _node_list.push_back(INodeHandle);
620 }
621
622 void MaxOptionsDialog::CullBadNodes() {
623 if (!_max_interface) return;
624 std::vector<ULONG> good;
625 for (int i=0; i<_node_list.size(); i++) {
626 ULONG handle = _node_list[i];
627 if (_max_interface->GetINodeByHandle(handle)) {
628 good.push_back(handle);
629 }
630 }
631 _node_list = good;
632 }
633
634 void MaxOptionsDialog::RemoveNode(int i) {
635 if (i >= 0 && i < _node_list.size()) {
636 for (int j = i+1; j < _node_list.size(); j++)
637 _node_list[i++] = _node_list[j++];
638 _node_list.pop_back();
639 }
640 }
641
642 void MaxOptionsDialog::RemoveNodeByHandle(ULONG INodeHandle) {
643 for (int i = 0; i < _node_list.size(); i++) {
644 if (_node_list[i] == INodeHandle) {
645 RemoveNode(i);
646 return;
647 }
648 }
649 }
650
651 IOResult MaxOptionsDialog::Save(ISave *isave) {
652 isave->BeginChunk(CHUNK_EGG_EXP_OPTIONS);
653 ChunkSave(isave, CHUNK_ANIM_TYPE, _anim_type);
654 ChunkSave(isave, CHUNK_FILENAME, _file_name);
655 ChunkSave(isave, CHUNK_SHORTNAME, _short_name);
656 ChunkSave(isave, CHUNK_SF, _start_frame);
657 ChunkSave(isave, CHUNK_EF, _end_frame);
658 ChunkSave(isave, CHUNK_DBL_SIDED, _double_sided);
659 ChunkSave(isave, CHUNK_EGG_CHECKED, _checked);
660 ChunkSave(isave, CHUNK_ALL_FRAMES, _export_all_frames);
661 ChunkSave(isave, CHUNK_EXPORT_FULL, _export_whole_scene);
662
663 isave->BeginChunk(CHUNK_NODE_LIST);
664 for (int i = 0; i < _node_list.size(); i++)
665 ChunkSave(isave, CHUNK_NODE_HANDLE, _node_list[i]);
666 isave->EndChunk();
667 isave->EndChunk();
668 return IO_OK;
669 }
670
671 IOResult MaxOptionsDialog::Load(ILoad *iload) {
672 IOResult res = iload->OpenChunk();
673
674 while (res == IO_OK) {
675 switch(iload->CurChunkID()) {
676 case CHUNK_ANIM_TYPE: _anim_type = (Anim_Type)ChunkLoadInt(iload); break;
677 case CHUNK_FILENAME: ChunkLoadString(iload, _file_name, sizeof(_file_name)); break;
678 case CHUNK_SHORTNAME: ChunkLoadString(iload, _short_name, sizeof(_short_name)); break;
679 case CHUNK_SF: _start_frame = ChunkLoadInt(iload); break;
680 case CHUNK_EF: _end_frame = ChunkLoadInt(iload); break;
681 case CHUNK_DBL_SIDED: _double_sided = ChunkLoadBool(iload); break;
682 case CHUNK_EGG_CHECKED: _checked = ChunkLoadBool(iload); break;
683 case CHUNK_ALL_FRAMES: _export_all_frames = ChunkLoadBool(iload); break;
684 case CHUNK_EXPORT_FULL: _export_whole_scene = ChunkLoadBool(iload); break;
685
686 case CHUNK_NODE_LIST:
687 res = iload->OpenChunk();
688 while (res == IO_OK) {
689 if (iload->CurChunkID() == CHUNK_NODE_HANDLE) AddNode(ChunkLoadULONG(iload));
690 iload->CloseChunk();
691 res = iload->OpenChunk();
692 }
693 break;
694 }
695 iload->CloseChunk();
696 res = iload->OpenChunk();
697 }
698
699 if (res == IO_END) return IO_OK;
700 return IO_ERROR;
701 }
MaxOptionsDialog
Definition: maxOptionsDialog.h:79
PathReplace
This encapsulates the user's command-line request to replace existing, incorrect pathnames to models ...
Definition: pathReplace.h:36
MaxEggOptions
Definition: maxOptionsDialog.h:51