MeshDeform.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* $Header: /Commando/Code/Tools/max2w3d/MeshDeform.cpp 7 5/01/01 8:56p Greg_h $ */
  19. /***********************************************************************************************
  20. *** Confidential - Westwood Studios ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Commando / G 3D engine *
  24. * *
  25. * File Name : MeshDeform.cpp *
  26. * *
  27. * Programmer : Patrick Smith *
  28. * *
  29. * Start Date : 04/19/99 *
  30. * *
  31. * Last Update :
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  36. #include "MeshDeform.H"
  37. #include "MeshDeformData.H"
  38. #include "MeshDeformPanel.H"
  39. #include "MeshDeformUndo.H"
  40. #include "DLLMain.H"
  41. #include "Resource.H"
  42. #include "Util.H"
  43. #if defined W3D_MAX4 //defined as in the project (.dsp)
  44. static GenSubObjType _SubObjectTypeVertex(1);
  45. #endif
  46. ///////////////////////////////////////////////////////////////////////////
  47. //
  48. // MeshDeformClass Class ID
  49. //
  50. ///////////////////////////////////////////////////////////////////////////
  51. Class_ID _MeshDeformClassID(0x51981f5b, 0x1db2bf3);
  52. ///////////////////////////////////////////////////////////////////////////
  53. //
  54. // MeshDeformClassDesc
  55. //
  56. ///////////////////////////////////////////////////////////////////////////
  57. class MeshDeformClassDesc : public ClassDesc
  58. {
  59. public:
  60. int IsPublic (void) { return 1; }
  61. void * Create (BOOL loading) { return new MeshDeformClass (); }
  62. const TCHAR * ClassName () { return _T("WWDeform"); }
  63. SClass_ID SuperClassID () { return OSM_CLASS_ID; }
  64. Class_ID ClassID () { return _MeshDeformClassID; }
  65. const TCHAR* Category () { return _T("Westwood Modifiers"); }
  66. };
  67. ///////////////////////////////////////////////////////////////////////////
  68. //
  69. // Static class desc instance
  70. //
  71. ///////////////////////////////////////////////////////////////////////////
  72. #if 0 // (gth) MeshDeform is obsolete! making sure nobody uses it...
  73. static MeshDeformClassDesc _MeshDeformCD;
  74. ClassDesc * Get_Mesh_Deform_Desc (void) { return &_MeshDeformCD; }
  75. #else
  76. ClassDesc * Get_Mesh_Deform_Desc (void) { return NULL; }
  77. #endif
  78. ///////////////////////////////////////////////////////////////////////////
  79. //
  80. // ChannelsUsed
  81. //
  82. ///////////////////////////////////////////////////////////////////////////
  83. ChannelMask
  84. MeshDeformClass::ChannelsUsed (void)
  85. {
  86. return GEOM_CHANNEL | SELECT_CHANNEL | SUBSEL_TYPE_CHANNEL | VERTCOLOR_CHANNEL;
  87. }
  88. ///////////////////////////////////////////////////////////////////////////
  89. //
  90. // ChannelsChanged
  91. //
  92. ///////////////////////////////////////////////////////////////////////////
  93. ChannelMask
  94. MeshDeformClass::ChannelsChanged (void)
  95. {
  96. return GEOM_CHANNEL | SELECT_CHANNEL | SUBSEL_TYPE_CHANNEL | VERTCOLOR_CHANNEL;
  97. }
  98. ///////////////////////////////////////////////////////////////////////////
  99. //
  100. // ModifyObject
  101. //
  102. ///////////////////////////////////////////////////////////////////////////
  103. void
  104. MeshDeformClass::ModifyObject
  105. (
  106. TimeValue time,
  107. ModContext & mod_context,
  108. ObjectState * object_state,
  109. INode * /*node*/
  110. )
  111. {
  112. assert(object_state->obj->IsSubClassOf(triObjectClassID));
  113. MeshDeformModData *mod_data = NULL;
  114. if (mod_context.localData == NULL) {
  115. mod_data = new MeshDeformModData;
  116. mod_context.localData = mod_data;
  117. } else {
  118. mod_data = static_cast <MeshDeformModData *> (mod_context.localData);
  119. }
  120. // Display the verts
  121. TriObject *tri_obj = (TriObject *)object_state->obj;
  122. tri_obj->mesh.SetDispFlag (DISP_SELVERTS | DISP_VERTTICKS);
  123. // Record the initial state of the mesh
  124. bool lock_sets = false;
  125. if (m_pPanel != NULL) {
  126. lock_sets = (m_pPanel->Are_Sets_Tied () == TRUE);
  127. }
  128. mod_data->Record_Mesh_State (*tri_obj, m_DeformState, lock_sets);
  129. tri_obj->PointsWereChanged();
  130. // Kind of a waste when there's no animation...
  131. tri_obj->UpdateValidity (GEOM_CHAN_NUM, Interval (time, time + 1));
  132. tri_obj->UpdateValidity (SELECT_CHAN_NUM, Interval (time, time + 1));
  133. tri_obj->UpdateValidity (SUBSEL_TYPE_CHAN_NUM, Interval (time, time + 1));
  134. return ;
  135. }
  136. ///////////////////////////////////////////////////////////////////////////
  137. //
  138. // InputType
  139. //
  140. ///////////////////////////////////////////////////////////////////////////
  141. Class_ID
  142. MeshDeformClass::InputType (void)
  143. {
  144. return triObjectClassID;
  145. }
  146. ///////////////////////////////////////////////////////////////////////////
  147. //
  148. // NotifyRefChanged
  149. //
  150. ///////////////////////////////////////////////////////////////////////////
  151. RefResult
  152. MeshDeformClass::NotifyRefChanged
  153. (
  154. Interval time,
  155. RefTargetHandle htarget,
  156. PartID &part_id,
  157. RefMessage mesage
  158. )
  159. {
  160. return REF_SUCCEED;
  161. }
  162. ///////////////////////////////////////////////////////////////////////////
  163. //
  164. // GetCreateMouseCallBack
  165. //
  166. ///////////////////////////////////////////////////////////////////////////
  167. CreateMouseCallBack *
  168. MeshDeformClass::GetCreateMouseCallBack (void)
  169. {
  170. return NULL;
  171. }
  172. ///////////////////////////////////////////////////////////////////////////
  173. //
  174. // BeginEditParams
  175. //
  176. ///////////////////////////////////////////////////////////////////////////
  177. void
  178. MeshDeformClass::BeginEditParams
  179. (
  180. IObjParam *max_interface,
  181. ULONG flags,
  182. Animatable *prev
  183. )
  184. {
  185. m_MaxInterface = max_interface;
  186. Update_Set_Count ();
  187. Set_Max_Deform_Sets (m_MaxSets);
  188. // Add our rollup to the command panel
  189. m_hRollupWnd = m_MaxInterface->AddRollupPage (AppInstance,
  190. MAKEINTRESOURCE (IDD_MESH_DEFORM_PANEL),
  191. MeshDeformPanelClass::Message_Proc,
  192. "Westwood Mesh Deform",
  193. 0,
  194. 0);
  195. //
  196. // Update the UI
  197. //
  198. m_pPanel = MeshDeformPanelClass::Get_Object (m_hRollupWnd);
  199. m_pPanel->Set_Deformer (this);
  200. m_pPanel->Set_Max_Sets (m_MaxSets);
  201. m_pPanel->Set_Current_Set (m_CurrentSet);
  202. Set_Current_Set (m_CurrentSet, false);
  203. //
  204. // Register the desired sub-object selection types.
  205. //
  206. const TCHAR * ptype[] = { "Vertices" };
  207. #if defined W3D_MAX4 //defined as in the project (.dsp)
  208. max_interface->SetSubObjectLevel(1);
  209. #else
  210. //---This call is obsolete from max4.
  211. max_interface->RegisterSubObjectTypes( ptype, 1);
  212. #endif
  213. //
  214. // Create the mode handlers
  215. //
  216. m_ModeSelect = new SelectModBoxCMode (this, max_interface);
  217. m_ModeMove = new MoveModBoxCMode (this, max_interface);
  218. m_ModeRotate = new RotateModBoxCMode (this, max_interface);
  219. m_ModeUScale = new UScaleModBoxCMode (this, max_interface);
  220. m_ModeNUScale = new NUScaleModBoxCMode (this, max_interface);
  221. m_ModeSquash = new SquashModBoxCMode (this, max_interface);
  222. //
  223. // Restore the selection level.
  224. ///
  225. max_interface->SetSubObjectLevel (1);
  226. return ;
  227. }
  228. ///////////////////////////////////////////////////////////////////////////
  229. //
  230. // EndEditParams
  231. //
  232. ///////////////////////////////////////////////////////////////////////////
  233. void
  234. MeshDeformClass::EndEditParams
  235. (
  236. IObjParam *max_interface,
  237. ULONG flags,
  238. Animatable *next
  239. )
  240. {
  241. // Remove our deform rollup
  242. if (m_hRollupWnd != NULL) {
  243. max_interface->DeleteRollupPage (m_hRollupWnd);
  244. m_hRollupWnd = NULL;
  245. }
  246. //
  247. // Free the mode handlers
  248. //
  249. max_interface->DeleteMode (m_ModeMove);
  250. max_interface->DeleteMode (m_ModeSelect);
  251. max_interface->DeleteMode (m_ModeRotate);
  252. max_interface->DeleteMode (m_ModeNUScale);
  253. max_interface->DeleteMode (m_ModeUScale);
  254. max_interface->DeleteMode (m_ModeSquash);
  255. SAFE_DELETE (m_ModeMove);
  256. SAFE_DELETE (m_ModeSelect);
  257. SAFE_DELETE (m_ModeRotate);
  258. SAFE_DELETE (m_ModeNUScale);
  259. SAFE_DELETE (m_ModeUScale);
  260. SAFE_DELETE (m_ModeSquash);
  261. // Release our hold on the max interface pointer
  262. m_MaxInterface = NULL;
  263. m_pPanel = NULL;
  264. return ;
  265. }
  266. ///////////////////////////////////////////////////////////////////////////
  267. //
  268. // ActivateSubobjSel
  269. //
  270. ///////////////////////////////////////////////////////////////////////////
  271. void
  272. MeshDeformClass::ActivateSubobjSel
  273. (
  274. int level,
  275. XFormModes &modes
  276. )
  277. {
  278. switch (level)
  279. {
  280. // Vertex manipulation
  281. case 1:
  282. modes = XFormModes (m_ModeMove, m_ModeRotate, m_ModeNUScale, m_ModeUScale, m_ModeSquash, m_ModeSelect);
  283. break;
  284. }
  285. /*
  286. ** Notify our dependents that the subselection type,
  287. ** and the display have changed
  288. */
  289. NotifyDependents(FOREVER, PART_SUBSEL_TYPE|PART_DISPLAY, REFMSG_CHANGE);
  290. /*
  291. ** Notify the pipeline that the selection level has changed.
  292. */
  293. m_MaxInterface->PipeSelLevelChanged();
  294. /*
  295. ** Notify our dependents that the selection channel,
  296. ** display attributes, and subselection type channels have changed
  297. */
  298. NotifyDependents(FOREVER, VERTCOLOR_CHANNEL|SELECT_CHANNEL|DISP_ATTRIB_CHANNEL|SUBSEL_TYPE_CHANNEL, REFMSG_CHANGE);
  299. return ;
  300. }
  301. ///////////////////////////////////////////////////////////////////////////
  302. //
  303. // HitTest
  304. //
  305. ///////////////////////////////////////////////////////////////////////////
  306. int
  307. MeshDeformClass::HitTest
  308. (
  309. TimeValue time_value,
  310. INode * node,
  311. int type,
  312. int crossing,
  313. int flags,
  314. IPoint2 * point,
  315. ViewExp * viewport,
  316. ModContext * mod_context
  317. )
  318. {
  319. // Initialize the HitRegion
  320. HitRegion hit_rgn;
  321. MakeHitRegion (hit_rgn, type, crossing, 4, point);
  322. Matrix3 transform = node->GetObjectTM (time_value);
  323. Object * obj = node->EvalWorldState(time_value).obj;
  324. TriObject * tri = (TriObject *)obj->ConvertToType(time_value, triObjectClassID);
  325. //
  326. // Set up the graphics window to do the hit-test
  327. //
  328. GraphicsWindow *graphics_wnd = viewport->getGW ();
  329. graphics_wnd->setHitRegion (&hit_rgn);
  330. graphics_wnd->setTransform (transform);
  331. int saved_limits = graphics_wnd->getRndLimits ();
  332. graphics_wnd->setRndLimits ((saved_limits | GW_PICK) & ~(GW_ILLUM | GW_BACKCULL));
  333. graphics_wnd->clearHitCode ();
  334. //
  335. // Perform the hit test
  336. //
  337. SubObjHitList hitlist;
  338. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context->localData);
  339. Mesh &mesh = tri->mesh;//mod_data->Peek_Mesh ();
  340. int result = mesh.SubObjectHitTest (graphics_wnd,
  341. graphics_wnd->getMaterial (),
  342. &hit_rgn,
  343. flags | SUBHIT_VERTS,
  344. hitlist);
  345. //
  346. // Record all of the hits
  347. //
  348. for (MeshSubHitRec *hit_record = hitlist.First ();
  349. hit_record != NULL;
  350. hit_record = hit_record->Next ()) {
  351. // rec->index is the index of vertex which was hit!
  352. viewport->LogHit (node, mod_context, hit_record->dist, hit_record->index, NULL);
  353. }
  354. // Cleanup
  355. graphics_wnd->setRndLimits (saved_limits);
  356. // Return the integer result code
  357. return result;
  358. }
  359. ///////////////////////////////////////////////////////////////////////////
  360. //
  361. // HitTest
  362. //
  363. ///////////////////////////////////////////////////////////////////////////
  364. void
  365. MeshDeformClass::SelectSubComponent
  366. (
  367. HitRecord * hit_record,
  368. BOOL selected,
  369. BOOL all,
  370. BOOL invert
  371. )
  372. {
  373. // Loop through all the hit records
  374. for (; hit_record != NULL; hit_record = hit_record->Next ()) {
  375. // Peek at the vertex selection array for this hit record
  376. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (hit_record->modContext->localData);
  377. Mesh *mesh = mod_data->Peek_Mesh ();
  378. BitArray &array = (mesh->vertSel);
  379. if (all & invert) {
  380. /*
  381. ** hitRec->hitInfo is the MeshSubHitRec::index that was stored in the
  382. ** HitTest method through LogHit
  383. */
  384. if (array[hit_record->hitInfo]) {
  385. array.Clear (hit_record->hitInfo);
  386. } else {
  387. array.Set (hit_record->hitInfo, selected);
  388. }
  389. } else {
  390. array.Set (hit_record->hitInfo, selected);
  391. }
  392. if (!all) break;
  393. }
  394. m_pPanel->Update_Vertex_Color ();
  395. NotifyDependents (FOREVER, PART_SELECT, REFMSG_CHANGE);
  396. m_bSetDirty = true;
  397. return ;
  398. }
  399. ///////////////////////////////////////////////////////////////////////////
  400. //
  401. // GetSubObjectTMs
  402. //
  403. ///////////////////////////////////////////////////////////////////////////
  404. void
  405. MeshDeformClass::GetSubObjectTMs
  406. (
  407. SubObjAxisCallback *cb,
  408. TimeValue t,
  409. INode *node,
  410. ModContext *mc
  411. )
  412. {
  413. int test = 0;
  414. return ;
  415. }
  416. ///////////////////////////////////////////////////////////////////////////
  417. //
  418. // HitTest
  419. //
  420. ///////////////////////////////////////////////////////////////////////////
  421. void
  422. MeshDeformClass::GetSubObjectCenters
  423. (
  424. SubObjAxisCallback * callback,
  425. TimeValue time_val,
  426. INode * node,
  427. ModContext * mod_context
  428. )
  429. {
  430. // Peek at the vertex selection array for this hit record
  431. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context->localData);
  432. const Point3 *vertex_array = mod_data->Peek_Orig_Vertex_Array ();
  433. Mesh *mesh = mod_data->Peek_Mesh ();
  434. BitArray sel_array = mesh->vertSel;
  435. Matrix3 transform = node->GetObjectTM (time_val);
  436. Box3 box;
  437. // Loop through all the selected verticies and create a bounding
  438. // box which we can use to determine the selection center.
  439. for (int index = 0; index < mesh->getNumVerts (); index++ ) {
  440. if (sel_array[index]) {
  441. box += mesh->getVert (index) * transform;
  442. }
  443. }
  444. // Pass the 'selection' center onto MAX
  445. callback->Center (box.Center (), 0);
  446. return ;
  447. }
  448. ///////////////////////////////////////////////////////////////////////////
  449. //
  450. // ClearSelection
  451. //
  452. ///////////////////////////////////////////////////////////////////////////
  453. void
  454. MeshDeformClass::ClearSelection (int selLevel)
  455. {
  456. ModContextList mod_context_list;
  457. INodeTab nodes;
  458. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  459. for (int i = 0; i < mod_context_list.Count (); i++) {
  460. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[i]->localData);
  461. if (mod_data != NULL) {
  462. mod_data->Peek_Mesh ()->vertSel.ClearAll ();
  463. }
  464. }
  465. /*
  466. ** Get rid of the temporary copies of the INodes.
  467. */
  468. nodes.DisposeTemporary ();
  469. /*
  470. ** Tell our dependents that the selection set has changed
  471. */
  472. NotifyDependents (FOREVER, PART_SELECT, REFMSG_CHANGE);
  473. m_bSetDirty = true;
  474. return ;
  475. }
  476. static Point3 last_delta;
  477. static Point3 last_scale;
  478. static Matrix3 last_rot;
  479. ///////////////////////////////////////////////////////////////////////////
  480. //
  481. // Move
  482. //
  483. ///////////////////////////////////////////////////////////////////////////
  484. void
  485. MeshDeformClass::Move
  486. (
  487. TimeValue time_val,
  488. Matrix3 & parent_tm,
  489. Matrix3 & tm_axis,
  490. Point3 & displacement,
  491. BOOL local_origin
  492. )
  493. {
  494. if (m_pPanel->Is_Edit_Mode ()) {
  495. INodeTab nodes;
  496. ModContextList mod_context_list;
  497. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  498. // Loop through all the modifier contexts
  499. for (int index = 0; index < mod_context_list.Count (); index ++) {
  500. // Get the data we've cached for this modifier context
  501. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  502. if (mod_data != NULL) {
  503. Mesh *mesh = mod_data->Peek_Mesh ();
  504. const Point3 *vertex_array = mod_data->Peek_Orig_Vertex_Array ();
  505. Point3 *opstart_array = mod_data->Peek_Vertex_OPStart_Array ();
  506. // Loop through all the selected verts
  507. for (int vert = 0; vert < mesh->numVerts; vert ++) {
  508. if (mesh->vertSel[vert]) {
  509. // Do the 'displacment' in axis-space
  510. Point3 vert_ws = parent_tm * mesh->verts[vert];
  511. Point3 vert_as = Inverse (tm_axis) * vert_ws;
  512. vert_as += displacement - last_delta;
  513. // Convert back to obj-space
  514. vert_ws = tm_axis * vert_as;
  515. mesh->verts[vert] = Inverse (parent_tm) * vert_ws;
  516. // Record the delta
  517. //delta_array[vert] = mesh->verts[vert] - vertex_array[vert];
  518. }
  519. }
  520. //
  521. // Record these changes in the current set
  522. //
  523. mod_data->Update_Set (m_CurrentSet, VERT_POSITION);
  524. }
  525. }
  526. // Remember what our last displacement was because we
  527. // want to perform our calculations relative to the current
  528. // position.
  529. last_delta = displacement;
  530. // Repaint the view
  531. nodes.DisposeTemporary ();
  532. NotifyDependents (FOREVER, PART_GEOM, REFMSG_CHANGE);
  533. }
  534. m_OperationName = "Move";
  535. return ;
  536. }
  537. ///////////////////////////////////////////////////////////////////////////
  538. //
  539. // Move
  540. //
  541. ///////////////////////////////////////////////////////////////////////////
  542. void
  543. MeshDeformClass::Scale
  544. (
  545. TimeValue time_val,
  546. Matrix3 & parent_tm,
  547. Matrix3 & tm_axis,
  548. Point3 & value,
  549. BOOL local_origin
  550. )
  551. {
  552. Point3 test = value - last_scale;
  553. bool bok = (test.x != 0) && (test.y != 0) && (test.z != 0);
  554. if (m_pPanel->Is_Edit_Mode () && bok) {
  555. INodeTab nodes;
  556. ModContextList mod_context_list;
  557. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  558. // Loop through all the modifier contexts
  559. for (int index = 0; index < mod_context_list.Count (); index ++) {
  560. // Get the data we've cached for this modifier context
  561. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  562. if (mod_data != NULL) {
  563. Mesh *mesh = mod_data->Peek_Mesh ();
  564. const Point3 *vertex_array = mod_data->Peek_Orig_Vertex_Array ();
  565. Point3 *opstart_array = mod_data->Peek_Vertex_OPStart_Array ();
  566. // Loop through all the selected verts
  567. for (int vert = 0; vert < mesh->numVerts; vert ++) {
  568. if (mesh->vertSel[vert]) {
  569. // Do the 'scale' in axis-space
  570. Point3 vert_ws = parent_tm * opstart_array[vert];//mesh->verts[vert];
  571. Point3 vert_as = Inverse (tm_axis) * vert_ws;
  572. vert_as = ScaleMatrix (value) * vert_as;
  573. // Convert back to obj-space
  574. vert_ws = tm_axis * vert_as;
  575. mesh->verts[vert] = Inverse (parent_tm) * vert_ws;
  576. // Record the delta
  577. //delta_array[vert] = mesh->verts[vert] - vertex_array[vert];
  578. }
  579. }
  580. //
  581. // Record these changes in the current set
  582. //
  583. mod_data->Update_Set (m_CurrentSet, VERT_POSITION);
  584. }
  585. }
  586. // Remember what our last displacement was because we
  587. // want to perform our calculations relative to the current
  588. // position.
  589. //last_scale = value - Point3 (1,1,1);
  590. //last_delta = displacement;
  591. // Repaint the view
  592. nodes.DisposeTemporary ();
  593. NotifyDependents (FOREVER, PART_GEOM, REFMSG_CHANGE);
  594. }
  595. m_OperationName = "Scale";
  596. return ;
  597. }
  598. ///////////////////////////////////////////////////////////////////////////
  599. //
  600. // Rotate
  601. //
  602. ///////////////////////////////////////////////////////////////////////////
  603. void
  604. MeshDeformClass::Rotate
  605. (
  606. TimeValue time_val,
  607. Matrix3 & parent_tm,
  608. Matrix3 & tm_axis,
  609. Quat & rotation,
  610. BOOL local_origin
  611. )
  612. {
  613. if (m_pPanel->Is_Edit_Mode ()) {
  614. INodeTab nodes;
  615. ModContextList mod_context_list;
  616. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  617. Matrix3 matrix_rot;
  618. rotation.MakeMatrix (matrix_rot);
  619. Matrix3 rel_rot;
  620. rel_rot = Inverse (last_rot) * matrix_rot;
  621. // Loop through all the modifier contexts
  622. for (int index = 0; index < mod_context_list.Count (); index ++) {
  623. // Get the data we've cached for this modifier context
  624. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  625. if (mod_data != NULL) {
  626. Mesh *mesh = mod_data->Peek_Mesh ();
  627. const Point3 *vertex_array = mod_data->Peek_Orig_Vertex_Array ();
  628. Point3 *opstart_array = mod_data->Peek_Vertex_OPStart_Array ();
  629. // Loop through all the selected verts
  630. for (int vert = 0; vert < mesh->numVerts; vert ++) {
  631. if (mesh->vertSel[vert]) {
  632. // Do the 'displacment' in axis-space
  633. Point3 vert_ws = parent_tm * mesh->verts[vert];
  634. Point3 vert_as = Inverse (tm_axis) * vert_ws;
  635. vert_as = (rel_rot * vert_as);
  636. // Convert back to obj-space
  637. vert_ws = tm_axis * vert_as;
  638. mesh->verts[vert] = Inverse (parent_tm) * vert_ws;
  639. // Record the delta
  640. //delta_array[vert] = mesh->verts[vert] - vertex_array[vert];
  641. }
  642. }
  643. //
  644. // Record these changes in the current set
  645. //
  646. mod_data->Update_Set (m_CurrentSet, VERT_POSITION);
  647. }
  648. }
  649. // Remember what our last displacement was because we
  650. // want to perform our calculations relative to the current
  651. // position.
  652. //last_delta = displacement;
  653. last_rot = matrix_rot;
  654. // Repaint the view
  655. nodes.DisposeTemporary ();
  656. NotifyDependents (FOREVER, PART_GEOM, REFMSG_CHANGE);
  657. // Make sure our current 'set' knows what verts have changed
  658. //Update_Current_Set ();
  659. }
  660. m_OperationName = "Rotate";
  661. return ;
  662. }
  663. ///////////////////////////////////////////////////////////////////////////
  664. //
  665. // TransformStart
  666. //
  667. ///////////////////////////////////////////////////////////////////////////
  668. void
  669. MeshDeformClass::TransformStart (TimeValue time_val)
  670. {
  671. if (m_MaxInterface != NULL) {
  672. m_MaxInterface->LockAxisTripods (TRUE);
  673. }
  674. // Reset our last-delta value
  675. last_delta.x = 0;
  676. last_delta.y = 0;
  677. last_delta.z = 0;
  678. last_rot.IdentityMatrix ();
  679. last_scale.x = 0;
  680. last_scale.y = 0;
  681. last_scale.z = 0;
  682. INodeTab nodes;
  683. ModContextList mod_context_list;
  684. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  685. // Begin the undo operation
  686. theHold.Begin ();
  687. // Loop through all the modifier contexts
  688. for (int index = 0; index < mod_context_list.Count (); index ++) {
  689. // Get the data we've cached for this modifier context
  690. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  691. if (mod_data != NULL) {
  692. Mesh *mesh = mod_data->Peek_Mesh ();
  693. Point3 *opstart_array = mod_data->Peek_Vertex_OPStart_Array ();
  694. // Copy the current state of the mesh
  695. for (int vert = 0; vert < mesh->numVerts; vert ++) {
  696. opstart_array[vert] = mesh->verts[vert];
  697. }
  698. // Add the 'position restore' object to the undo stack
  699. theHold.Put (new VertexPositionRestoreClass (mesh, this, mod_data));
  700. }
  701. }
  702. // Repaint the view
  703. nodes.DisposeTemporary ();
  704. NotifyDependents (FOREVER, PART_GEOM, REFMSG_CHANGE);
  705. return ;
  706. }
  707. ///////////////////////////////////////////////////////////////////////////
  708. //
  709. // TransformFinish
  710. //
  711. ///////////////////////////////////////////////////////////////////////////
  712. void
  713. MeshDeformClass::TransformFinish (TimeValue time_val)
  714. {
  715. if (m_MaxInterface != NULL) {
  716. m_MaxInterface->LockAxisTripods (FALSE);
  717. }
  718. // Accept the undo operation
  719. theHold.Accept (m_OperationName);
  720. return ;
  721. }
  722. ///////////////////////////////////////////////////////////////////////////
  723. //
  724. // TransformCancel
  725. //
  726. ///////////////////////////////////////////////////////////////////////////
  727. void
  728. MeshDeformClass::TransformCancel (TimeValue time_val)
  729. {
  730. if (m_MaxInterface != NULL) {
  731. m_MaxInterface->LockAxisTripods (FALSE);
  732. }
  733. // Cancel the undo operation
  734. theHold.Cancel ();
  735. return ;
  736. }
  737. ///////////////////////////////////////////////////////////////////////////
  738. //
  739. // Set_Deform_State
  740. //
  741. ///////////////////////////////////////////////////////////////////////////
  742. void
  743. MeshDeformClass::Set_Deform_State (float state)
  744. {
  745. if ((m_MaxInterface != NULL) && (state != m_DeformState)) {
  746. m_DeformState = state;
  747. NotifyDependents (FOREVER, PART_GEOM | PART_VERTCOLOR, REFMSG_CHANGE);
  748. m_MaxInterface->RedrawViews (m_MaxInterface->GetTime ());
  749. if (m_pPanel != NULL) {
  750. m_pPanel->Update_Vertex_Color ();
  751. }
  752. }
  753. return ;
  754. }
  755. ///////////////////////////////////////////////////////////////////////////
  756. //
  757. // Set_Vertex_Color
  758. //
  759. ///////////////////////////////////////////////////////////////////////////
  760. void
  761. MeshDeformClass::Set_Vertex_Color (const Point3 &color, bool button_up)
  762. {
  763. if (m_MaxInterface != NULL) {
  764. INodeTab nodes;
  765. ModContextList mod_context_list;
  766. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  767. bool save_undo = false;
  768. if ((button_up == false) && (m_VertColorChanging == false)) {
  769. theHold.Begin ();
  770. m_VertColorChanging = true;
  771. save_undo = true;
  772. }
  773. // Loop through all the modifier contexts
  774. for (int index = 0; index < mod_context_list.Count (); index ++) {
  775. // Get the data we've cached for this modifier context
  776. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  777. if (mod_data != NULL) {
  778. Mesh *mesh = mod_data->Peek_Mesh ();
  779. //
  780. // Record the original color in the undo stack
  781. //
  782. if (save_undo) {
  783. theHold.Put (new VertexColorRestoreClass (mesh, this, mod_data));
  784. }
  785. // Only do this if the mesh is using vertex coloring
  786. if (mesh->numCVerts >= mesh->numVerts) {
  787. //
  788. // Loop through all the per-face verts
  789. //
  790. for (int face = 0; face < mesh->numFaces; face ++) {
  791. for (int vert = 0; vert < 3; vert ++) {
  792. //
  793. // If the vertex is selected, then change its color
  794. //
  795. if (mesh->vertSel[mesh->faces[face].v[vert]]) {
  796. int color_index = mesh->vcFace[face].t[vert];
  797. mesh->vertCol[color_index] = color;
  798. }
  799. }
  800. }
  801. }
  802. //
  803. // Record these changes in the current set
  804. //
  805. mod_data->Update_Set (m_CurrentSet, VERT_COLORS);
  806. }
  807. }
  808. if (button_up && m_VertColorChanging) {
  809. theHold.Accept ("Vertex Color");
  810. }
  811. // Repaint the model
  812. nodes.DisposeTemporary ();
  813. NotifyDependents (FOREVER, PART_GEOM | PART_VERTCOLOR, REFMSG_CHANGE);
  814. m_MaxInterface->RedrawViews (m_MaxInterface->GetTime ());
  815. }
  816. m_VertColorChanging = !button_up;
  817. return ;
  818. }
  819. ///////////////////////////////////////////////////////////////////////////
  820. //
  821. // Get_Vertex_Color
  822. //
  823. ///////////////////////////////////////////////////////////////////////////
  824. void
  825. MeshDeformClass::Get_Vertex_Color (Point3 &color)
  826. {
  827. // Assume black
  828. color.x = 0;
  829. color.y = 0;
  830. color.z = 0;
  831. if (m_MaxInterface != NULL) {
  832. INodeTab nodes;
  833. ModContextList mod_context_list;
  834. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  835. //
  836. // Loop through all the modifier contexts
  837. //
  838. int sel_count = 0;
  839. for (int index = 0; index < mod_context_list.Count (); index ++) {
  840. //
  841. // Get the data we've cached for this modifier context
  842. //
  843. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  844. if (mod_data != NULL) {
  845. Mesh *mesh = mod_data->Peek_Mesh ();
  846. // Only do this if the mesh is using vertex coloring
  847. if (mesh->numCVerts >= mesh->numVerts) {
  848. //
  849. // Loop through all the per-face verts
  850. //
  851. for (int face = 0; face < mesh->numFaces; face ++) {
  852. for (int vert = 0; vert < 3; vert ++) {
  853. //
  854. // If this vert is selected, then add its color to the total
  855. //
  856. if (mesh->vertSel[mesh->faces[face].v[vert]]) {
  857. int color_index = mesh->vcFace[face].t[vert];
  858. Point3 vert_color = mesh->vertCol[color_index];
  859. color += vert_color;
  860. sel_count ++;
  861. }
  862. }
  863. }
  864. }
  865. }
  866. }
  867. //
  868. // Normalize the selected color
  869. //
  870. if (sel_count > 0) {
  871. color = color / sel_count;
  872. }
  873. nodes.DisposeTemporary ();
  874. }
  875. return ;
  876. }
  877. ///////////////////////////////////////////////////////////////////////////
  878. //
  879. // Update_UI
  880. //
  881. ///////////////////////////////////////////////////////////////////////////
  882. void
  883. MeshDeformClass::Update_UI (MeshDeformModData *mod_data)
  884. {
  885. assert (mod_data != NULL);
  886. if (m_pPanel != NULL) {
  887. Update_Set_Count ();
  888. m_CurrentSet = mod_data->Get_Current_Set ();
  889. int keyframe = mod_data->Peek_Set (m_CurrentSet).Get_Current_Key_Frame ();
  890. Set_Deform_State ((float(keyframe + 1) + 0.5F) / 10.0F);
  891. m_pPanel->Update_Vertex_Color ();
  892. m_pPanel->Set_Max_Sets (m_MaxSets);
  893. m_pPanel->Set_Current_Set (m_CurrentSet);
  894. m_pPanel->Set_Current_State (m_DeformState);
  895. }
  896. return ;
  897. }
  898. ///////////////////////////////////////////////////////////////////////////
  899. //
  900. // Auto_Apply
  901. //
  902. ///////////////////////////////////////////////////////////////////////////
  903. void
  904. MeshDeformClass::Auto_Apply (bool auto_apply)
  905. {
  906. if (m_MaxInterface != NULL) {
  907. // Get a list of contexts that we are part of.
  908. INodeTab nodes;
  909. ModContextList mod_context_list;
  910. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  911. // Loop through all the modifier contexts
  912. for (int index = 0; index < mod_context_list.Count (); index ++) {
  913. //
  914. // Let the mod context know what it's auto apply state is
  915. //
  916. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  917. if (mod_data != NULL) {
  918. mod_data->Auto_Apply (auto_apply);
  919. }
  920. }
  921. // Cleanup
  922. nodes.DisposeTemporary ();
  923. }
  924. return ;
  925. }
  926. ///////////////////////////////////////////////////////////////////////////
  927. //
  928. // Set_Max_Deform_Sets
  929. //
  930. ///////////////////////////////////////////////////////////////////////////
  931. void
  932. MeshDeformClass::Set_Max_Deform_Sets (int max)
  933. {
  934. //
  935. // Make sure the current set doesn't exceed the total sets
  936. //
  937. if (m_CurrentSet >= max) {
  938. Set_Current_Set (max - 1, true);
  939. }
  940. m_MaxSets = max;
  941. if (m_MaxInterface != NULL) {
  942. // Get a list of contexts that we are part of.
  943. INodeTab nodes;
  944. ModContextList mod_context_list;
  945. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  946. // Loop through all the modifier contexts
  947. for (int index = 0; index < mod_context_list.Count (); index ++) {
  948. //
  949. // Let the mod context know the max sets have changed
  950. //
  951. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  952. if (mod_data != NULL) {
  953. mod_data->Set_Max_Deform_Sets (max);
  954. }
  955. }
  956. // Cleanup
  957. nodes.DisposeTemporary ();
  958. NotifyDependents (FOREVER, PART_SELECT, REFMSG_CHANGE);
  959. m_MaxInterface->RedrawViews (m_MaxInterface->GetTime ());
  960. }
  961. return ;
  962. }
  963. ///////////////////////////////////////////////////////////////////////////
  964. //
  965. // Update_Set_Count
  966. //
  967. ///////////////////////////////////////////////////////////////////////////
  968. void
  969. MeshDeformClass::Update_Set_Count (void)
  970. {
  971. m_MaxSets = 1;
  972. if (m_MaxInterface != NULL) {
  973. // Get a list of contexts that we are part of.
  974. INodeTab nodes;
  975. ModContextList mod_context_list;
  976. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  977. // Loop through all the modifier contexts
  978. for (int index = 0; index < mod_context_list.Count (); index ++) {
  979. //
  980. // Get the count of sets for this context
  981. //
  982. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  983. if ((mod_data != NULL) && (mod_data->Get_Set_Count () > m_MaxSets)) {
  984. m_MaxSets = mod_data->Get_Set_Count ();
  985. }
  986. }
  987. // Cleanup
  988. nodes.DisposeTemporary ();
  989. }
  990. return ;
  991. }
  992. ///////////////////////////////////////////////////////////////////////////
  993. //
  994. // Set_Current_Set
  995. //
  996. ///////////////////////////////////////////////////////////////////////////
  997. void
  998. MeshDeformClass::Set_Current_Set
  999. (
  1000. int index,
  1001. bool update_selection
  1002. )
  1003. {
  1004. last_delta.x = 0;
  1005. last_delta.y = 0;
  1006. last_delta.z = 0;
  1007. m_CurrentSet = index;
  1008. if (m_MaxInterface != NULL) {
  1009. if (update_selection) {
  1010. ClearSelection (1);
  1011. }
  1012. // Get a list of contexts that we are part of.
  1013. INodeTab nodes;
  1014. ModContextList mod_context_list;
  1015. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  1016. // Loop through all the modifier contexts
  1017. for (int index = 0; index < mod_context_list.Count (); index ++) {
  1018. //
  1019. // Have the mod context select the verts in its set
  1020. //
  1021. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  1022. if (mod_data != NULL) {
  1023. mod_data->Set_Current_Set (m_CurrentSet);
  1024. if (update_selection) {
  1025. mod_data->Select_Set (m_CurrentSet);
  1026. }
  1027. m_pPanel->Set_Auto_Apply_Check (mod_data->Is_Auto_Apply ());
  1028. }
  1029. }
  1030. // Repaint the model
  1031. nodes.DisposeTemporary ();
  1032. if (update_selection) {
  1033. NotifyDependents (FOREVER, PART_SELECT, REFMSG_CHANGE);
  1034. m_MaxInterface->RedrawViews (m_MaxInterface->GetTime ());
  1035. }
  1036. // Update the current 'vertex color' on the UI panel
  1037. m_pPanel->Update_Vertex_Color ();
  1038. }
  1039. return ;
  1040. }
  1041. ///////////////////////////////////////////////////////////////////////////
  1042. //
  1043. // Update_Current_Set
  1044. //
  1045. ///////////////////////////////////////////////////////////////////////////
  1046. void
  1047. MeshDeformClass::Update_Current_Set (void)
  1048. {
  1049. if (m_MaxInterface != NULL) {
  1050. // Get a list of contexts that we are part of.
  1051. INodeTab nodes;
  1052. ModContextList mod_context_list;
  1053. m_MaxInterface->GetModContexts (mod_context_list, nodes);
  1054. // Loop through all the modifier contexts
  1055. for (int index = 0; index < mod_context_list.Count (); index ++) {
  1056. //
  1057. // Notify the mod context so it can update its list of verts
  1058. // in the current set.
  1059. //
  1060. MeshDeformModData *mod_data = static_cast <MeshDeformModData *> (mod_context_list[index]->localData);
  1061. if (mod_data != NULL) {
  1062. //mod_data->Update_Set (m_CurrentSet);
  1063. }
  1064. }
  1065. // Cleanup
  1066. nodes.DisposeTemporary ();
  1067. m_bSetDirty = false;
  1068. }
  1069. return ;
  1070. }
  1071. ///////////////////////////////////////////////////////////////////////////
  1072. //
  1073. // SaveLocalData
  1074. //
  1075. ///////////////////////////////////////////////////////////////////////////
  1076. IOResult
  1077. MeshDeformClass::SaveLocalData (ISave *save_obj, LocalModData *mod_context)
  1078. {
  1079. assert (mod_context != NULL);
  1080. return ((MeshDeformModData *)mod_context)->Save (save_obj);
  1081. }
  1082. ///////////////////////////////////////////////////////////////////////////
  1083. //
  1084. // LoadLocalData
  1085. //
  1086. ///////////////////////////////////////////////////////////////////////////
  1087. IOResult
  1088. MeshDeformClass::LoadLocalData (ILoad *load_obj, LocalModData **mod_context)
  1089. {
  1090. assert (mod_context != NULL);
  1091. MeshDeformModData *mod_data = new MeshDeformModData;
  1092. (*mod_context) = mod_data;
  1093. return mod_data->Load (load_obj);
  1094. }
  1095. #if 0
  1096. void SkinModifierClass::SelectAll(int selLevel)
  1097. {
  1098. int needsdel = 0;
  1099. Interval valid = FOREVER;
  1100. ModContextList mclist;
  1101. INodeTab nodes;
  1102. if (!InterfacePtr) return;
  1103. InterfacePtr->GetModContexts(mclist,nodes);
  1104. InterfacePtr->ClearCurNamedSelSet();
  1105. for (int i = 0; i < mclist.Count(); i++) {
  1106. SkinDataClass * skindata = (SkinDataClass *)mclist[i]->localData;
  1107. if (skindata==NULL) continue;
  1108. ObjectState os = nodes[i]->EvalWorldState(InterfacePtr->GetTime());
  1109. TriObject * tobj = Get_Tri_Object(InterfacePtr->GetTime(),os,valid,needsdel);
  1110. switch (SubObjSelLevel) {
  1111. case OBJECT_SEL_LEVEL:
  1112. assert(0);
  1113. return;
  1114. case VERTEX_SEL_LEVEL:
  1115. #if 0 // undo/redo
  1116. if (theHold.Holding()) {
  1117. theHold.Put(new VertexSelRestore(meshData,this));
  1118. }
  1119. #endif
  1120. tobj->mesh.vertSel.SetAll();
  1121. skindata->VertSel.SetAll();
  1122. break;
  1123. }
  1124. if (needsdel) {
  1125. tobj->DeleteThis();
  1126. }
  1127. }
  1128. /*
  1129. ** Get rid of the temporary copies of the INodes.
  1130. */
  1131. nodes.DisposeTemporary();
  1132. /*
  1133. ** Tell our dependents that the selection set has changed
  1134. */
  1135. NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
  1136. }
  1137. void SkinModifierClass::InvertSelection(int selLevel)
  1138. {
  1139. int needsdel = 0;
  1140. Interval valid = FOREVER;
  1141. ModContextList mclist;
  1142. INodeTab nodes;
  1143. if (!InterfacePtr) return;
  1144. InterfacePtr->GetModContexts(mclist,nodes);
  1145. InterfacePtr->ClearCurNamedSelSet();
  1146. for (int i = 0; i < mclist.Count(); i++) {
  1147. SkinDataClass * skindata = (SkinDataClass *)mclist[i]->localData;
  1148. if (skindata==NULL) continue;
  1149. ObjectState os = nodes[i]->EvalWorldState(InterfacePtr->GetTime());
  1150. TriObject * tobj = Get_Tri_Object(InterfacePtr->GetTime(),os,valid,needsdel);
  1151. switch (SubObjSelLevel) {
  1152. case OBJECT_SEL_LEVEL:
  1153. assert(0);
  1154. return;
  1155. case VERTEX_SEL_LEVEL:
  1156. #if 0 // undo/redo
  1157. if (theHold.Holding()) {
  1158. theHold.Put(new VertexSelRestore(meshData,this));
  1159. }
  1160. #endif
  1161. for (int j=0; j<tobj->mesh.vertSel.GetSize(); j++) {
  1162. if (tobj->mesh.vertSel[j]) tobj->mesh.vertSel.Clear(j);
  1163. else tobj->mesh.vertSel.Set(j);
  1164. }
  1165. skindata->VertSel = tobj->mesh.vertSel;
  1166. break;
  1167. }
  1168. if (needsdel) {
  1169. tobj->DeleteThis();
  1170. }
  1171. }
  1172. /*
  1173. ** Get rid of the temporary copies of the INodes.
  1174. */
  1175. nodes.DisposeTemporary();
  1176. /*
  1177. ** Tell our dependents that the selection set has changed
  1178. */
  1179. NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
  1180. }
  1181. #endif // 0
  1182. #if defined W3D_MAX4 //defined as in the project (.dsp)
  1183. ////////////////////////////////////////////////////////////////////////////////////////
  1184. int MeshDeformClass::NumSubObjTypes()
  1185. {
  1186. return 1;
  1187. }
  1188. ////////////////////////////////////////////////////////////////////////////////////////
  1189. ISubObjType *MeshDeformClass::GetSubObjType(int i)
  1190. {
  1191. static bool _initialized = false;
  1192. if(!_initialized){
  1193. _initialized = true;
  1194. _SubObjectTypeVertex.SetName("Vertices");
  1195. }
  1196. if(i == -1){
  1197. if(GetSubObjectLevel() > 0){
  1198. return GetSubObjType(GetSubObjectLevel()-1);
  1199. }
  1200. }
  1201. return &_SubObjectTypeVertex;
  1202. }
  1203. #endif