Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**********************************************************************
- *<
- FILE: BSDismemberSkin.cpp
- DESCRIPTION: Mesh and Skin Import routines
- CREATED BY: Blabba
- HISTORY:
- *> Copyright (c) 2015, All Rights Reserved.
- **********************************************************************/
- #include <max.h>
- #include <meshdlib.h>
- // #include <afxwin.h>
- #include "..\NifProps\iNifProps.h"
- #include "NifGui.h"
- // #include "utilapi.h"
- // Class Definitions
- #define WM_UPDATE_CACHE (WM_USER + 0x2000)
- #ifndef MESHSELECTCONVERT_INTERFACE
- #define MESHSELECTCONVERT_INTERFACE Interface_ID(0x3da7dd5, 0x7ecf0391)
- #endif
- // Button Definitions
- #define IDC_SELVERTEX 0x3260
- #define IDC_SELEDGE 0x3261
- #define IDC_SELFACE 0x3262
- #define IDC_SELPOLY 0x3263
- #define IDC_SELELEMENT 0x3264
- // extern int *meshSubTypeToolbarIDs;
- // MeshSelMod flags:
- #define MS_DISP_END_RESULT 0x01
- // BSDSModifier References:
- #define REF_PBLOCK 0
- // Local static class instances
- static BSDSImageHandler theBSDSImageHandler;
- static BSDSPartImageHandler theBSDSPartImageHandler;
- // static GenSubObjType SOT_Vertex(_M("Vertex"), _M("SubObjectIcons"), 1);
- // static GenSubObjType SOT_Edge(_M("Edge"), _M("SubObjectIcons"), 2);
- static GenSubObjType SOT_Face(_M("Face"), _M("SubObjectIcons"), 3);
- static GenSubObjType SOT_Poly(_M("Poly"), _M("SubObjectIcons"), 4);
- static GenSubObjType SOT_Element(_M("Element"), _M("SubObjectIcons"), 5);
- // Enum Lookup types for display in drowpdown list
- const EnumLookupType GameFlags[] = {
- { DismemberPartition::NoGame, _T("No Game") },
- { DismemberPartition::Skyrim, _T("Skyrim") },
- { DismemberPartition::Fallout_NV, _T("Fallout: New Vegas") },
- { DismemberPartition::Fallout_3, _T("Fallout_3") },
- { DismemberPartition::Oblivion, _T("Oblivion") },
- { DismemberPartition::Morrowind, _T("Morrowind") },
- };
- // Forward class declaration for GetModifierData();
- class BSDSData;
- // Main BSDismember Class Definition
- class BSDSModifier : public Modifier, public IBSDismemberSkinModifier, public FlagUser {
- public:
- IParamBlock2 *pblock;
- static IObjParam *ip;
- static BSDSModifier *editMod;
- static SelectModBoxCMode *selectMode;
- static BOOL updateCachePosted;
- // Default Constructor
- BSDSModifier();
- // Animatable Class Overrides
- void DeleteThis() { delete this; }
- void GetClassName(TSTR& s) { s = GetString(IDS_RB_BSDSMODIFIER); }
- virtual Class_ID ClassID() { return BSDSMODIFIER_CLASS_ID; }
- RefTargetHandle Clone(RemapDir& remap /*= DefaultRemapDir()*/);
- const TCHAR *GetObjectName() { return GetString(IDS_RB_BSDSMODIFIER); }
- void* GetInterface(ULONG id) { return (id == I_BSDISMEMBERSKINMODIFIER) ? (IBSDismemberSkinModifier*) this : Modifier::GetInterface(id); }
- // Modifier Class Overrides
- ChannelMask ChannelsUsed() { return PART_GEOM | PART_TOPO; }
- ChannelMask ChannelsChanged() { return PART_SELECT | PART_SUBSEL_TYPE | PART_TOPO | PART_GEOM; }
- Class_ID InputType() { return triObjectClassID; }
- void ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node);
- Interval LocalValidity(TimeValue t);
- Interval GetValidity(TimeValue t);
- BOOL DependOnTopology(ModContext &mc) { return TRUE; }
- // BaseObject Class Overrides
- CreateMouseCallBack* GetCreateMouseCallBack() { return NULL; }
- void BeginEditParams(IObjParam *ip, ULONG flags, Animatable *prev);
- void EndEditParams(IObjParam *ip, ULONG flags, Animatable *next);
- int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc);
- int Display(TimeValue t, INode* inode, ViewExp *vpt, int flagst, ModContext *mc);
- void ActivateSubobjSel(int level, XFormModes& modes);
- void SelectSubComponent(HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert = FALSE);
- void ClearSelection(int selLevel);
- void SelectAll(int selLevel);
- void InvertSelection(int selLevel);
- void NotifyInputChanged(Interval changeInt, PartID partID, RefMessage message, ModContext *mc);
- void ShowEndResultChanged(BOOL showEndResult) { NotifyDependents(FOREVER, PART_DISPLAY, REFMSG_CHANGE); }
- BOOL SupportsNamedSubSels() { return FALSE; }
- // Unsure if needed?
- // void ActivateSubSelSet(int index);
- // New SubObjType API
- int NumSubObjTypes();
- ISubObjType *GetSubObjType(int i);
- // IO Class Overrides
- IOResult Save(ISave *isave);
- IOResult Load(ILoad *iload);
- IOResult SaveLocalData(ISave *isave, LocalModData *ld);
- IOResult LoadLocalData(ILoad *iload, LocalModData **pld);
- int NumParamBlocks() { return 1; }
- IParamBlock2 *GetParamBlock(int i) { return pblock; }
- IParamBlock2 *GetParamBlockByID(short id) { return (pblock->ID() == id) ? pblock : NULL; }
- int NumRefs() { return 1; }
- RefTargetHandle GetReference(int i) { return pblock; }
- private:
- virtual void SetReference(int i, RefTargetHandle rtarg) { pblock = (IParamBlock2 *)rtarg; }
- public:
- int NumSubs() { return 1; }
- Animatable* SubAnim(int i) { return GetReference(i); }
- TSTR SubAnimName(int i) { return GetString(IDS_RB_PARAMETERS); }
- RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
- // Modifier Methods
- void UpdateSelLevelDisplay();
- void SetEnableStates();
- void SelectByMatID(int id);
- void SetNumSelLabel();
- void UpdateCache(TimeValue t);
- void InvalidateDialogElement(int elem);
- void LocalDataChanged();
- void SelectUnused();
- IBSDismemberSkinModifierData *GetModifierDataInterface();
- BSDSData* GetModifierData();
- };
- class BSDSData : public LocalModData, public IBSDismemberSkinModifierData {
- private:
- // Temp data used for soft selections, adjacent edge / face lists.
- MeshTempData *temp;
- public:
- // Get Interface of this type of LocalModData
- void* GetInterface(ULONG id) { if (id == I_BSDISMEMBERSKINMODIFIERDATA) return(IMeshSelectData*)this; else return LocalModData::GetInterface(id); }
- // Selection sets
- // Tab<BitArray> vertSel;
- Tab<BitArray> faceSel;
- // Tab<BitArray> edgeSel;
- BOOL held;
- Mesh *mesh;
- int currentPartition;
- Tab<DismemberPartition> bodyParts;
- // BSDSData functions
- BSDSData(Mesh &mesh);
- // Re-define later and initialize 3 different BitArray's that are empty and append them to the tab
- BSDSData();
- ~BSDSData() { FreeCache(); }
- LocalModData *Clone();
- Mesh *GetMesh() { return mesh; }
- AdjEdgeList *GetAdjEdgeList();
- AdjFaceList *GetAdjFaceList();
- void SetCache(Mesh &mesh);
- void FreeCache();
- void SynchBitArrays();
- void SelVertByFace();
- void SelVertByEdge();
- void SelFaceByVert();
- void SelFaceByEdge();
- void SelPolygonByVert(float thresh, int igVis);
- void SelPolygonByEdge(float thresh, int igVis);
- void SelElementByVert();
- void SelElementByEdge();
- void SelEdgeByVert();
- void SelEdgeByFace();
- // void SetVertSel(BitArray &set, BSDSModifier *imod, TimeValue t);
- void SetFaceSel(BitArray &set, BSDSModifier *imod, TimeValue t);
- // void SetEdgeSel(BitArray set, BSDSModifier *imod, TimeValue t);
- void SetFaceSel(BitArray &set, IBSDismemberSkinModifier *imod, TimeValue t) { SetFaceSel(set, (BSDSModifier*)imod, t); }
- // void SetEdgeSel(BitArray set, IBSDismemberSkinModifier *imod, TimeValue t) { SetFaceSel(set, (BSDSModifier*)imod, t); }
- Tab<DismemberPartition> GetDismembers() { return bodyParts; }
- BitArray GetFaceSel() { return faceSel[currentPartition]; }
- // BitArray GetEdgeSel() { return edgeSel[currentPartition]; }
- // Custom Methods
- int AddPartition();
- void RemovePartition(int num);
- int GetCurrentPartition() { return currentPartition; }
- int GetNumPartitions() { return bodyParts.Count(); }
- BitArray GetUnused();
- // Note:Zero indexed
- void SetCurrentPartition(int i) { (i < bodyParts.Count()) ? currentPartition = i : currentPartition; }
- };
- // Proc Class for getting Modifier local data.Maybe change this later?
- class SelectModContextEnumProc : public ModContextEnumProc {
- public:
- virtual BOOL proc(ModContext *mc) {
- data = (LocalModData*)mc->localData;
- /*if (!data) {
- data = (LocalModData*)&manual;
- mc->localData = data;
- }*/
- return TRUE;
- }
- LocalModData *data;
- // BSDSData manual;
- };
- // Sub-Class Overrides
- class SelectRestore : public RestoreObj {
- public:
- BitArray usel, rsel;
- BitArray *sel;
- BSDSModifier *mod;
- BSDSData *d;
- int level;
- SelectRestore(BSDSModifier *m, BSDSData *d);
- // SelectRestore(BSDSModifier *m, BSDSData *d, int level);
- void Restore(int isUndo);
- void Redo();
- int Size() { return 1; }
- void EndHold() { d->held = FALSE; }
- TSTR Description() { return TSTR(_T("SelectRestore")); }
- };
- //-------------------------------- ClassDescriptor and Class Vars ----------------------------------
- IObjParam *BSDSModifier::ip = NULL;
- BSDSModifier *BSDSModifier::editMod = NULL;
- SelectModBoxCMode *BSDSModifier::selectMode = NULL;
- BOOL BSDSModifier::updateCachePosted = FALSE;
- class BSDSClassDesc :public ClassDesc2 {
- public:
- // BSDSClassDesc();
- int IsPublic() { return 1; }
- void * Create(BOOL loading = FALSE) { return new BSDSModifier; }
- const TCHAR * ClassName() { return GetString(IDS_RB_BSDSMODIFIER); }
- SClass_ID SuperClassID() { return OSM_CLASS_ID; }
- Class_ID ClassID() { return BSDSMODIFIER_CLASS_ID; }
- const TCHAR* Category() { return GetString(IDS_CATEGORY); }
- const TCHAR * InternalName() { return _T("BSDSModifier"); }
- HINSTANCE HInstance() { return hInstance; }
- };
- static BSDSClassDesc BSDSDesc;
- ClassDesc2* GetBSDSModifierDesc() { return &BSDSDesc; }
- /*BSDSClassDesc::BSDSClassDesc() {
- BSDS_desc.SetClassDesc(this);
- }*/
- class BSDSModifierMainDlgProc : public ParamMap2UserDlgProc {
- public:
- BSDSModifier *mod;
- BSDSModifierMainDlgProc() { mod = NULL; }
- void SetEnables(HWND hWnd);
- void UpdateSelLevelDisplay(HWND hWnd);
- INT_PTR DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
- void DeleteThis() { }
- NpComboBox gameList;
- // NpComboBox dismemberList;
- ISpinnerControl *mActivePart;
- ICustButton *mAddPart;
- ICustButton *mDelPart;
- };
- static BSDSModifierMainDlgProc theBSDSModifierMainDlgProc;
- // Table to convert selLevel values to mesh selLevel flags.
- const int meshLevel[] = { MESH_OBJECT, /*MESH_VERTEX, MESH_EDGE,*/ MESH_FACE, MESH_FACE, MESH_FACE };
- // Get display flags based on selLevel.
- const DWORD levelDispFlags[] = { 0, /*DISP_VERTTICKS | DISP_SELVERTS, DISP_SELEDGES,*/ DISP_SELFACES, DISP_SELPOLYS, DISP_SELPOLYS };
- // For hit testing...
- const int hitLevel[] = { 0, /*SUBHIT_VERTS, SUBHIT_EDGES,*/ SUBHIT_FACES, SUBHIT_FACES, SUBHIT_FACES };
- // Parameter block IDs:
- // Blocks themselves:
- enum { ms_pblock };
- // Parameter maps:
- enum { ms_map_main };
- // Parameters in first block:
- enum { ms_by_vertex, ms_ignore_backfacing, ms_matid, ms_ignore_visible, ms_planar_threshold, };
- static ParamBlockDesc2 BSDS_desc(ms_pblock,
- _T("BSDismemberSkinDescription"),
- IDS_MS_SOFTSEL, &BSDSDesc,
- P_AUTO_CONSTRUCT | P_AUTO_UI | P_MULTIMAP,
- REF_PBLOCK,
- //rollout descriptions
- 1,
- ms_map_main, IDD_BSDS_SELECT, IDS_MS_PARAMS, 0, 0, NULL,
- // params
- ms_by_vertex, _T("byVertex"), TYPE_BOOL, P_RESET_DEFAULT, IDS_BY_VERTEX,
- p_default, false,
- p_ui, ms_map_main, TYPE_SINGLECHEKBOX, IDC_MS_SEL_BYVERT,
- p_end,
- ms_ignore_backfacing, _T("ignoreBackfacing"), TYPE_BOOL, P_RESET_DEFAULT, IDS_IGNORE_BACKFACING,
- p_default, false,
- p_ui, ms_map_main, TYPE_SINGLECHEKBOX, IDC_MS_IGNORE_BACKFACES,
- p_end,
- ms_matid, _T("materialID"), TYPE_INT, P_TRANSIENT | P_RESET_DEFAULT, IDS_RB_MATERIALID,
- p_default, 1,
- p_range, 1, 65535,
- p_ui, ms_map_main, TYPE_SPINNER, EDITTYPE_INT,
- IDC_MS_MATID, IDC_MS_MATIDSPIN, .5f,
- p_end,
- ms_ignore_visible, _T("ignoreVisibleEdges"), TYPE_BOOL, P_RESET_DEFAULT, IDS_IGNORE_VISIBLE,
- p_default, false,
- p_ui, ms_map_main, TYPE_SINGLECHEKBOX, IDC_MS_IGNORE_VISEDGE,
- p_end,
- ms_planar_threshold, _T("planarThreshold"), TYPE_ANGLE, P_RESET_DEFAULT, IDS_RB_THRESHOLD,
- p_default, PI / 4.0f, // Default value for angles has to be in radians.
- p_range, 0.0f, 180.0f, // but range given in degrees.
- p_ui, ms_map_main, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
- IDC_MS_PLANAR, IDC_MS_PLANARSPINNER, .1f,
- p_end,
- p_end
- );
- //-------------------------------- BDSDSModifier Methods ----------------------------------
- BSDSData *BSDSModifier::GetModifierData() {
- SelectModContextEnumProc selector;
- this->EnumModContexts(&selector);
- BSDSData *testData = dynamic_cast<BSDSData*>(selector.data);
- return testData;
- }
- IBSDismemberSkinModifierData *BSDSModifier::GetModifierDataInterface() {
- SelectModContextEnumProc selector;
- this->EnumModContexts(&selector);
- BSDSData *testData = dynamic_cast<BSDSData*>(selector.data);
- if (!testData)
- return NULL;
- if (IBSDismemberSkinModifierData *modData = static_cast<IBSDismemberSkinModifierData*>(testData->GetInterface(I_BSDISMEMBERSKINMODIFIERDATA)))
- return modData;
- return NULL;
- }
- BSDSModifier::BSDSModifier() {
- pblock = NULL;
- BSDSDesc.MakeAutoParamBlocks(this);
- assert(pblock);
- }
- RefTargetHandle BSDSModifier::Clone(RemapDir& remap) {
- BSDSModifier *mod = new BSDSModifier();
- mod->ReplaceReference(0, remap.CloneRef(pblock));
- BaseClone(this, mod, remap);
- return mod;
- }
- Interval BSDSModifier::LocalValidity(TimeValue t) {
- // If we are being edited, return NEVER to forces a cache to be built after previous modifier.
- if (TestAFlag(A_MOD_BEING_EDITED))
- return NEVER;
- return GetValidity(t);
- }
- Interval BSDSModifier::GetValidity(TimeValue t) { return FOREVER; }
- void BSDSModifier::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node) {
- if (!os->obj->IsSubClassOf(triObjectClassID)) return;
- TriObject *tobj = (TriObject*)os->obj;
- BSDSData *d = dynamic_cast<BSDSData*>(mc.localData);
- if (!d) mc.localData = d = new BSDSData(tobj->GetMesh());
- // BitArray vertSel = d->vertSel[d->currentPartition];
- BitArray faceSel = d->faceSel[d->currentPartition];
- // BitArray edgeSel = d->edgeSel[d->currentPartition];
- // vertSel.SetSize(tobj->GetMesh().getNumVerts(), TRUE);
- faceSel.SetSize(tobj->GetMesh().getNumFaces(), TRUE);
- // edgeSel.SetSize(tobj->GetMesh().getNumFaces() * 3, TRUE);
- // tobj->GetMesh().vertSel = vertSel;
- tobj->GetMesh().faceSel = faceSel;
- // tobj->GetMesh().edgeSel = edgeSel;
- tobj->GetMesh().selLevel = meshLevel[d->bodyParts[d->currentPartition].selLevel];
- Interval outValid = tobj->ChannelValidity(t, SELECT_CHAN_NUM);
- // Update the cache used for display, hit-testing:
- if (!d->GetMesh()) d->SetCache(tobj->GetMesh());
- else *(d->GetMesh()) = tobj->GetMesh();
- // Set display flags - but be sure to turn off vertex display in stack result if
- // "Show End Result" is turned on - we want the user to just see the Mesh Select
- // level vertices (from the Display method).
- tobj->GetMesh().dispFlags = 0;
- if (/*d->bodyParts[d->currentPartition].selLevel != SEL_VERTEX ||*/ !ip || !ip->GetShowEndResult())
- tobj->GetMesh().SetDispFlag(levelDispFlags[d->bodyParts[d->currentPartition].selLevel]);
- tobj->SetChannelValidity(SELECT_CHAN_NUM, outValid);
- // Maybe un-needed?
- // LocalDataChanged();
- }
- void BSDSModifier::NotifyInputChanged(Interval changeInt, PartID partID, RefMessage message, ModContext *mc) {
- if (!mc->localData) return;
- if (partID == PART_SELECT) return;
- ((BSDSData*)mc->localData)->FreeCache();
- if (!BSDSDesc.NumParamMaps()) return;
- IParamMap2 *pmap = BSDSDesc.GetParamMap(ms_map_main);
- if (!pmap) return;
- HWND hWnd = pmap->GetHWnd();
- if (!hWnd) return;
- TimeValue t = ip->GetTime();
- PostMessage(hWnd, WM_UPDATE_CACHE, (WPARAM)t, 0);
- updateCachePosted = TRUE;
- }
- void BSDSModifier::UpdateCache(TimeValue t) {
- NotifyDependents(Interval(t, t), PART_GEOM | SELECT_CHANNEL | PART_SUBSEL_TYPE | PART_DISPLAY | PART_TOPO, REFMSG_MOD_EVAL);
- updateCachePosted = FALSE;
- }
- void BSDSModifier::UpdateSelLevelDisplay() {
- if (theBSDSModifierMainDlgProc.mod != this) return;
- if (!BSDSDesc.NumParamMaps()) return;
- IParamMap2 *pmap = BSDSDesc.GetParamMap(ms_map_main);
- if (!pmap) return;
- HWND hWnd = pmap->GetHWnd();
- if (!hWnd) return;
- theBSDSModifierMainDlgProc.UpdateSelLevelDisplay(hWnd);
- }
- static int butIDs[] = { 0, IDC_SELFACE, IDC_SELPOLY, IDC_SELELEMENT };
- void BSDSModifierMainDlgProc::UpdateSelLevelDisplay(HWND hWnd) {
- if (!mod) return;
- BSDSData *d = mod->GetModifierData();
- int selLevel, nParts, nActive;
- if (!d) {
- selLevel = SEL_OBJECT;
- nParts = 1;
- nActive = 0;
- gameList.select(1);
- // dismemberList.SelectString(_T("Body"));
- }
- else {
- selLevel = d->bodyParts[d->currentPartition].selLevel;
- nParts = d->bodyParts.Count();
- nActive = d->currentPartition;
- gameList.select(d->bodyParts[d->currentPartition].thisGame);
- // dismemberList.SelectString(d->bodyParts[d->currentPartition].currentSlot.c_str());
- }
- ICustToolbar *iToolbar = GetICustToolbar(GetDlgItem(hWnd, IDC_MS_SELTYPE));
- ICustButton *but;
- int level = mod->ip->GetSubObjectLevel();
- // DWORD selLevel = d->bodyParts[d->currentPartition].selLevel;
- for (int i = 1; i< 4; i++) {
- but = iToolbar->GetICustButton(butIDs[i]);
- but->SetCheck(level != 0 && i == selLevel);
- ReleaseICustButton(but);
- }
- ReleaseICustToolbar(iToolbar);
- if (mActivePart) {
- // int nParts = d->GetNumPartitions();
- // int nActive = d->currentPartition;
- mActivePart->SetLimits(0, nParts - 1, TRUE);
- mActivePart->SetValue(nActive, 0);
- }
- // gameList.select(EnumToIndex(d->bodyParts[d->currentPartition].thisGame, GameFlags));
- // DismemberList Update May work?
- // dismemberList.SelectString(d->bodyParts[d->currentPartition].currentSlot.c_str());
- UpdateWindow(hWnd);
- }
- static bool oldShowEnd;
- void BSDSModifier::BeginEditParams(IObjParam *ip, ULONG flags, Animatable *prev) {
- this->ip = ip;
- editMod = this;
- // Use our classdesc2 to put up our parammap2 maps:
- BSDSDesc.BeginEditParams(ip, this, flags, prev);
- theBSDSModifierMainDlgProc.mod = this;
- BSDSDesc.SetUserDlgProc(&BSDS_desc, ms_map_main, &theBSDSModifierMainDlgProc);
- selectMode = new SelectModBoxCMode(this, ip);
- // Restore the selection level.
- // ip->SetSubObjectLevel( GetActivePartition() + 1 );
- SetEnableStates();
- UpdateSelLevelDisplay();
- SetNumSelLabel();
- // Set show end result.
- oldShowEnd = ip->GetShowEndResult() ? TRUE : FALSE;
- ip->SetShowEndResult(GetFlag(MS_DISP_END_RESULT));
- // NotifyDependents(FOREVER, PART_ALL, REFMSG_NUM_SUBOBJECTTYPES_CHANGED);
- TimeValue t = ip->GetTime();
- NotifyDependents(Interval(t, t), PART_ALL, REFMSG_BEGIN_EDIT);
- NotifyDependents(Interval(t, t), PART_ALL, REFMSG_MOD_DISPLAY_ON);
- SetAFlag(A_MOD_BEING_EDITED);
- // Ensure creation of local mod data
- // ip->GetSelNode(0)->EvalWorldState(0);
- }
- void BSDSModifier::EndEditParams(IObjParam *ip, ULONG flags, Animatable *next) {
- BSDSDesc.EndEditParams(ip, this, flags, next);
- theBSDSModifierMainDlgProc.mod = NULL;
- ip->DeleteMode(selectMode);
- if (selectMode) delete selectMode;
- selectMode = NULL;
- // Reset show end result
- SetFlag(MS_DISP_END_RESULT, ip->GetShowEndResult() ? TRUE : FALSE);
- ip->SetShowEndResult(oldShowEnd);
- this->ip = NULL;
- editMod = NULL;
- TimeValue t = ip->GetTime();
- ClearAFlag(A_MOD_BEING_EDITED);
- NotifyDependents(Interval(t, t), PART_ALL, REFMSG_END_EDIT);
- NotifyDependents(Interval(t, t), PART_ALL, REFMSG_MOD_DISPLAY_OFF);
- }
- int BSDSModifier::HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc) {
- if (!vpt || !vpt->IsAlive()) {
- // ViewPort Error
- DbgAssert(!_T("Invalid viewport!"));
- return FALSE;
- }
- Interval valid;
- int savedLimits, res = 0;
- GraphicsWindow *gw = vpt->getGW();
- HitRegion hr;
- int selByVert, ignoreBackfaces;
- pblock->GetValue(ms_by_vertex, t, selByVert, FOREVER);
- pblock->GetValue(ms_ignore_backfacing, t, ignoreBackfaces, FOREVER);
- // Setup GW
- MakeHitRegion(hr, type, crossing, 4, p);
- gw->setHitRegion(&hr);
- Matrix3 mat = inode->GetObjectTM(t);
- gw->setTransform(mat);
- gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM);
- if (ignoreBackfaces) gw->setRndLimits(gw->getRndLimits() | GW_BACKCULL);
- else gw->setRndLimits(gw->getRndLimits() & ~GW_BACKCULL);
- gw->clearHitCode();
- SubObjHitList hitList;
- MeshSubHitRec *rec;
- if (!mc->localData || !((BSDSData*)mc->localData)->GetMesh()) return 0;
- BSDSData *d = (BSDSData*)mc->localData;
- DWORD hitFlags;
- if (selByVert) {
- hitFlags = SUBHIT_VERTS;
- // if (d->bodyParts[d->currentPartition].selLevel > SEL_VERTEX) hitFlags |= SUBHIT_USEFACESEL;
- if (d->bodyParts[d->currentPartition].selLevel > SEL_OBJECT) hitFlags |= SUBHIT_USEFACESEL;
- }
- else {
- hitFlags = hitLevel[d->bodyParts[d->currentPartition].selLevel];
- }
- Mesh &mesh = *(d)->GetMesh();
- // cache backfacing vertices as hidden:
- BitArray oldHide;
- if ((hitFlags & SUBHIT_VERTS) && ignoreBackfaces) {
- BOOL flip = mat.Parity();
- oldHide = mesh.vertHide;
- BitArray faceBack;
- faceBack.SetSize(mesh.getNumFaces());
- faceBack.ClearAll();
- for (int i = 0; i<mesh.getNumFaces(); i++) {
- DWORD *vv = mesh.faces[i].v;
- IPoint3 A[3];
- for (int j = 0; j<3; j++) gw->wTransPoint(&(mesh.verts[vv[j]]), &(A[j]));
- IPoint3 d1 = A[1] - A[0];
- IPoint3 d2 = A[2] - A[0];
- if (flip) {
- if ((d1^d2).z > 0) continue;
- }
- else {
- if ((d1^d2).z < 0) continue;
- }
- for (int j = 0; j<3; j++) mesh.vertHide.Set(vv[j]);
- faceBack.Set(i);
- }
- for (int i = 0; i<mesh.getNumFaces(); i++) {
- if (faceBack[i]) continue;
- DWORD *vv = mesh.faces[i].v;
- for (int j = 0; j<3; j++) mesh.vertHide.Clear(vv[j]);
- }
- mesh.vertHide |= oldHide;
- }
- res = mesh.SubObjectHitTest(gw, gw->getMaterial(), &hr, flags | hitFlags, hitList);
- if ((hitFlags & SUBHIT_VERTS) && ignoreBackfaces) mesh.vertHide = oldHide;
- rec = hitList.First();
- while (rec) {
- vpt->LogHit(inode, mc, rec->dist, rec->index, NULL);
- rec = rec->Next();
- }
- gw->setRndLimits(savedLimits);
- return res;
- }
- int BSDSModifier::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags, ModContext *mc) {
- if (!vpt || !vpt->IsAlive())
- {
- // why are we here
- DbgAssert(!_T("Invalid viewport!"));
- return FALSE;
- }
- if (!ip || !ip->GetShowEndResult()) return 0;
- if (!mc->localData) return 0;
- BSDSData *modData = (BSDSData*)mc->localData;
- if (!modData->currentPartition) return 0;
- Mesh *mesh = modData->GetMesh();
- if (!mesh) return 0;
- // Set up GW
- GraphicsWindow *gw = vpt->getGW();
- Matrix3 tm = inode->GetObjectTM(t);
- int savedLimits;
- gw->setRndLimits((savedLimits = gw->getRndLimits()) & ~GW_ILLUM);
- gw->setTransform(tm);
- // We need to draw a "gizmo" version of the mesh:
- Point3 colSel = GetSubSelColor();
- Point3 colTicks = GetUIColor(COLOR_VERT_TICKS);
- Point3 colGiz = GetUIColor(COLOR_GIZMOS);
- Point3 colGizSel = GetUIColor(COLOR_SEL_GIZMOS);
- gw->setColor(LINE_COLOR, colGiz);
- AdjEdgeList *ae = modData->GetAdjEdgeList();
- Point3 rp[3];
- int i, ect = ae->edges.Count();
- #ifdef MESH_CAGE_BACKFACE_CULLING
- // Figure out backfacing from frontfacing.
- BitArray fBackfacing, vBackfacing;
- bool backCull = (savedLimits & GW_BACKCULL) ? true : false;
- if (backCull)
- {
- fBackfacing.SetSize(mesh->numFaces);
- vBackfacing.SetSize(mesh->numVerts);
- vBackfacing.SetAll();
- BitArray nonIsoVerts;
- nonIsoVerts.SetSize(mesh->numVerts);
- mesh->checkNormals(false); // Allocates rVerts.
- RVertex *rv = mesh->getRVertPtr(0);
- BOOL gwFlipped = gw->getFlipped();
- for (i = 0; i <mesh->numVerts; i++) {
- rv[i].rFlags = (rv[i].rFlags & ~(GW_PLANE_MASK | RND_MASK | RECT_MASK)) |
- gw->hTransPoint(&(mesh->verts[i]), (IPoint3 *)rv[i].pos);
- }
- for (i = 0; i<mesh->numFaces; i++)
- {
- Face & f = mesh->faces[i];
- fBackfacing.Set(i, hIsFacingBack(rv[f.v[0]].pos, rv[f.v[1]].pos, rv[f.v[2]].pos, gwFlipped));
- for (int j = 0; j<3; j++) nonIsoVerts.Set(f.v[j]);
- if (fBackfacing[i]) continue;
- for (int j = 0; j<3; j++) vBackfacing.Clear(f.v[j]);
- }
- vBackfacing &= nonIsoVerts; // so isolated vertices aren't labeled as backfacing.
- }
- #endif
- int es[3];
- gw->startSegments();
- for (i = 0; i<ect; i++) {
- MEdge & me = ae->edges[i];
- if (me.Hidden(mesh->faces)) continue;
- if (me.Visible(mesh->faces)) {
- es[0] = GW_EDGE_VIS;
- }
- else {
- // if (modData->bodyParts[modData->currentPartition].selLevel < SEL_EDGE) continue;
- if (modData->bodyParts[modData->currentPartition].selLevel == SEL_OBJECT) continue;
- if (modData->bodyParts[modData->currentPartition].selLevel > SEL_FACE) continue;
- es[0] = GW_EDGE_INVIS;
- }
- #ifdef MESH_CAGE_BACKFACE_CULLING
- if (backCull && fBackfacing[me.f[0]] && ((me.f[1] == UNDEFINED) || fBackfacing[me.f[1]]))
- continue;
- #endif
- /*if (modData->bodyParts[modData->currentPartition].selLevel == SEL_EDGE) {
- // Unsure if correct? Need Memory address but returning a pointer?
- if (ae->edges[i].Selected(mesh->faces, modData->edgeSel[modData->currentPartition])) gw->setColor(LINE_COLOR, colGizSel);
- else gw->setColor(LINE_COLOR, colGiz);
- }*/
- if (modData->bodyParts[modData->currentPartition].selLevel >= SEL_FACE) {
- // Unsure if correct? Need Memory address but returning a pointer?
- if (ae->edges[i].AFaceSelected(modData->faceSel[modData->currentPartition])) gw->setColor(LINE_COLOR, colGizSel);
- else gw->setColor(LINE_COLOR, colGiz);
- }
- rp[0] = mesh->verts[me.v[0]];
- rp[1] = mesh->verts[me.v[1]];
- //gw->polyline (2, rp, NULL, NULL, FALSE, es);
- if (es[0] == GW_EDGE_VIS)
- gw->segment(rp, 1);
- else gw->segment(rp, 0);
- }
- gw->endSegments();
- }
- void BSDSModifier::ActivateSubobjSel(int level, XFormModes& modes) {
- BSDSData *modData = GetModifierData();
- // Set the meshes level
- modData->bodyParts[modData->currentPartition].selLevel = level;
- // Fill in modes with our sub-object modes
- if (level != SEL_OBJECT) {
- modes = XFormModes(NULL, NULL, NULL, NULL, NULL, selectMode);
- }
- // Update UI
- UpdateSelLevelDisplay();
- SetEnableStates();
- SetNumSelLabel();
- NotifyDependents(FOREVER, PART_ALL, PART_SUBSEL_TYPE | PART_DISPLAY, REFMSG_CHANGE);
- // Not needed since this modifier is only there to store selection face data for nif export, not modelling
- // ip->PipeSelLevelChanged();
- // NotifyDependents(FOREVER, SELECT_CHANNEL | DISP_ATTRIB_CHANNEL | SUBSEL_TYPE_CHANNEL, REFMSG_CHANGE);
- }
- void BSDSModifier::LocalDataChanged() {
- // BOOL changed = FALSE;
- BSDSData *modData = GetModifierData();
- if (!modData) return;
- // Setup Sub-Objects
- // changed = (subObjects.Count() != modData->bodyParts.Count());
- // subObjects.SetCount(modData->bodyParts.Count());
- /*for (int i = 0; i < subObjects.Count(); i++) {
- TSTR name(modData->bodyParts[i].currentSlot.c_str());
- subObjects[i].SetName(name);
- changed |= (name != subObjects[i].GetNameRef()) ? true : false;
- }*/
- /*if (changed)
- NotifyDependents(FOREVER, PART_ALL, REFMSG_NUM_SUBOBJECTTYPES_CHANGED);
- else
- NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);*/
- NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
- if (ip && editMod == this)
- SetNumSelLabel();
- }
- void BSDSModifier::SelectSubComponent(HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert) {
- BSDSData *d = NULL,*od = NULL;
- int selByVert, ignoreVisEdge;
- float planarThresh;
- TimeValue t = ip->GetTime();
- pblock->GetValue(ms_by_vertex, t, selByVert, FOREVER);
- pblock->GetValue(ms_ignore_visible, t, ignoreVisEdge, FOREVER);
- pblock->GetValue(ms_planar_threshold, t, planarThresh, FOREVER);
- // int nd;
- BitArray nsel;
- AdjEdgeList *ae = NULL;
- AdjFaceList *af = NULL;
- Mesh *mesh;
- d = (BSDSData*)GetModifierData();
- // if (!d) return;
- HitRecord *hr = hitRec;
- // if (!all && (hr->modContext->localData != d)) return;
- for (; hr != NULL; hr = hr->Next()) if (hr->modContext->localData == d) break;
- // if (!hr) return;
- mesh = d->GetMesh();
- // if (!mesh) return;
- BaseInterface *msci = mesh->GetInterface(MESHSELECTCONVERT_INTERFACE);
- if (selByVert) {
- ae = d->GetAdjEdgeList();
- // if (!ae) return;
- }
- int selectLevel = d->bodyParts[d->currentPartition].selLevel;
- switch (selectLevel) {
- // case SEL_VERTEX: break;
- /*case SEL_EDGE:
- if (msci && selByVert) {
- // Use new improved selection conversion:
- BitArray vhit;
- vhit.SetSize(mesh->numVerts);
- for (hr = hitRec; hr != NULL; hr = hr->Next()) {
- if (d != hr->modContext->localData) continue;
- vhit.Set(hr->hitInfo);
- if (!all) break;
- }
- #if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0)
- MeshSelectionConverter *pConv = static_cast<MeshSelectionConverter*>(msci);
- pConv->VertexToEdge(*mesh, vhit, nsel);
- if (invert) nsel ^= d->edgeSel[d->currentPartition];
- else {
- if (selected) nsel |= d->edgeSel[d->currentPartition];
- else nsel = d->edgeSel[d->currentPartition] & ~nsel;
- }
- #endif
- }
- else {
- BitArray &edgeSel = d->edgeSel[d->currentPartition];
- nsel = d->edgeSel[d->currentPartition];
- for (; hr != NULL; hr = hr->Next()) {
- if (d != hr->modContext->localData) continue;
- if (selByVert) {
- DWORDTab & list = ae->list[hr->hitInfo];
- for (int i = 0; i < list.Count(); i++) {
- MEdge & me = ae->edges[list[i]];
- for (int j = 0; j < 2; j++) {
- if (me.f[j] == UNDEFINED) continue;
- DWORD ei = mesh->faces[me.f[j]].GetEdgeIndex(me.v[0], me.v[1]);
- if (ei > 2) continue;
- ei += me.f[j] * 3;
- nsel.Set(ei, invert ? !edgeSel[ei] : selected);
- }
- }
- }
- else {
- nsel.Set(hr->hitInfo, invert ? !edgeSel[hr->hitInfo] : selected);
- }
- if (!all) break;
- }
- }
- d->SetEdgeSel(nsel, this, t);
- break;*/
- case SEL_FACE:
- if (msci && selByVert) {
- // Use new improved selection conversion:
- BitArray vhit;
- vhit.SetSize(mesh->numVerts);
- for (hr = hitRec; hr != NULL; hr = hr->Next()) {
- if (d != hr->modContext->localData) continue;
- vhit.Set(hr->hitInfo);
- if (!all) break;
- }
- #if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0)
- MeshSelectionConverter *pConv = static_cast<MeshSelectionConverter*>(msci);
- pConv->VertexToFace(*mesh, vhit, nsel);
- if (invert) nsel ^= d->faceSel[d->currentPartition];
- else {
- if (selected) nsel |= d->faceSel[d->currentPartition];
- else nsel = d->faceSel[d->currentPartition] & ~nsel;
- }
- #endif
- }
- else {
- // BitArray &faceSel = d->faceSel[d->currentPartition];
- nsel = d->faceSel[d->currentPartition];
- for (; hr != NULL; hr = hr->Next()) {
- if (d != hr->modContext->localData) continue;
- if (selByVert) {
- DWORDTab & list = ae->list[hr->hitInfo];
- for (int i = 0; i < list.Count(); i++) {
- MEdge & me = ae->edges[list[i]];
- for (int j = 0; j < 2; j++) {
- if (me.f[j] == UNDEFINED) continue;
- nsel.Set(me.f[j], invert ? !d->faceSel[d->currentPartition][me.f[j]] : selected);
- }
- }
- }
- else {
- nsel.Set(hr->hitInfo, invert ? !d->faceSel[d->currentPartition][hr->hitInfo] : selected);
- }
- if (!all) break;
- }
- }
- d->SetFaceSel(nsel, this, t);
- break;
- case SEL_POLY:
- case SEL_ELEMENT:
- af = d->GetAdjFaceList();
- if (msci) {
- // Use new improved selection conversion:
- #if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0)
- MeshSelectionConverter *pConv = static_cast<MeshSelectionConverter*>(msci);
- if (selByVert) {
- BitArray vhit;
- vhit.SetSize(mesh->numVerts);
- for (hr = hitRec; hr != NULL; hr = hr->Next()) {
- if (d != hr->modContext->localData) continue;
- vhit.Set(hr->hitInfo);
- if (!all) break;
- }
- if (selectLevel == SEL_ELEMENT) pConv->VertexToElement(*mesh, af, vhit, nsel);
- else pConv->VertexToPolygon(*mesh, af, vhit, nsel, planarThresh, ignoreVisEdge ? true : false);
- }
- else {
- BitArray fhit;
- fhit.SetSize(mesh->numFaces);
- for (hr = hitRec; hr != NULL; hr = hr->Next()) {
- if (d != hr->modContext->localData) continue;
- fhit.Set(hr->hitInfo);
- if (!all) break;
- }
- if (selectLevel == SEL_ELEMENT) pConv->FaceToElement(*mesh, af, fhit, nsel);
- else pConv->FaceToPolygon(*mesh, af, fhit, nsel, planarThresh, ignoreVisEdge ? true : false);
- }
- #endif
- }
- else {
- // Otherwise we'll take the old approach of converting faces to polygons or elements as we go.
- nsel.SetSize(mesh->numFaces);
- nsel.ClearAll();
- for (; hr != NULL; hr = hr->Next()) {
- if (d != hr->modContext->localData) continue;
- if (!selByVert) {
- if (selectLevel == SEL_ELEMENT)
- mesh->ElementFromFace(hr->hitInfo, nsel, af);
- else
- mesh->PolyFromFace(hr->hitInfo, nsel, planarThresh, ignoreVisEdge, af);
- }
- else {
- DWORDTab & list = ae->list[hr->hitInfo];
- for (int i = 0; i < list.Count(); i++) {
- MEdge & me = ae->edges[list[i]];
- for (int j = 0; j < 2; j++) {
- if (me.f[j] == UNDEFINED) continue;
- if (selectLevel == SEL_ELEMENT)
- mesh->ElementFromFace(me.f[j], nsel, af);
- else
- mesh->PolyFromFace(me.f[j], nsel, planarThresh, ignoreVisEdge, af);
- }
- }
- }
- if (!all) break;
- }
- }
- if (invert) nsel ^= d->faceSel[d->currentPartition];
- else if (selected) nsel |= d->faceSel[d->currentPartition];
- else nsel = d->faceSel[d->currentPartition] & ~nsel;
- d->SetFaceSel(nsel, this, t);
- break;
- }
- LocalDataChanged();
- }
- void BSDSModifier::ClearSelection(int selLevel) {
- if (!ip) return;
- BSDSData *d = (BSDSData*)GetModifierData();
- if (!d) return;
- // int selectionLevel = d->bodyParts[d->currentPartition].selLevel;
- if (theHold.Holding() && !d->held) theHold.Put(new SelectRestore(this, d));
- d->SynchBitArrays();
- switch (selLevel) {
- // case SEL_VERTEX: break;
- case SEL_FACE:
- case SEL_POLY:
- case SEL_ELEMENT:
- d->faceSel[d->currentPartition].ClearAll();
- break;
- /*case SEL_EDGE:
- d->edgeSel[d->currentPartition].ClearAll();
- break;*/
- }
- LocalDataChanged();
- }
- void BSDSModifier::SelectAll(int selLevel) {
- if (!ip) return;
- if (selLevel == SEL_OBJECT) return;
- BSDSData *d = GetModifierData();
- if (!d) return;
- // int selectionLevel = d->bodyParts[d->currentPartition].selLevel;
- if (theHold.Holding() && !d->held) theHold.Put(new SelectRestore(this, d));
- d->SynchBitArrays();
- switch (selLevel) {
- // case SEL_VERTEX: break;
- case SEL_FACE:
- case SEL_POLY:
- case SEL_ELEMENT:
- d->faceSel[d->currentPartition].SetAll();
- break;
- /*case SEL_EDGE:
- d->edgeSel[d->currentPartition].SetAll();
- break;*/
- }
- LocalDataChanged();
- }
- void BSDSModifier::InvertSelection(int selLevel) {
- if (!ip) return;
- BSDSData *d = (BSDSData*)GetModifierData();
- if (!d) return;
- // int selectionLevel = d->bodyParts[d->currentPartition].selLevel;
- if (theHold.Holding() && !d->held) theHold.Put(new SelectRestore(this, d));
- d->SynchBitArrays();
- switch (selLevel) {
- // case SEL_VERTEX: break;
- case SEL_FACE:
- case SEL_POLY:
- case SEL_ELEMENT:
- d->faceSel[d->currentPartition].Reverse();
- break;
- /*case SEL_EDGE:
- d->edgeSel[d->currentPartition].Reverse();
- break;*/
- }
- LocalDataChanged();
- }
- void BSDSModifier::SelectByMatID(int id) {
- if (!ip) return;
- BOOL add = GetKeyState(VK_CONTROL) < 0 ? TRUE : FALSE;
- BOOL sub = GetKeyState(VK_MENU) < 0 ? TRUE : FALSE;
- theHold.Begin();
- BSDSData *d = (BSDSData*)GetModifierData();
- // if (!d) return;
- if (!d->held) theHold.Put(new SelectRestore(this, d));
- d->SynchBitArrays();
- if (!add && !sub) d->faceSel[d->currentPartition].ClearAll();
- Mesh *mesh = d->GetMesh();
- // if (!mesh) return;
- for (int i = 0; i<mesh->numFaces; i++) {
- if (mesh->faces[i].getMatID() == (MtlID)id) {
- if (sub) d->faceSel[d->currentPartition].Clear(i);
- else d->faceSel[d->currentPartition].Set(i);
- }
- }
- theHold.Accept(GetString(IDS_RB_SELECTBYMATID));
- LocalDataChanged();
- ip->RedrawViews(ip->GetTime());
- }
- //-------------------------------- BDSDSModifier I/O Methods ----------------------------------
- // old-style parameter block for loading old scenes:
- #define NUM_OLDVERSIONS 0
- // #define SELLEVEL_CHUNKID 0x0100
- #define FLAGS_CHUNKID 0x0240
- #define VERSION_CHUNKID 0x0230
- static int currentVersion = 1;
- // #define NAMEDVSEL_NAMES_CHUNK 0x2805
- // #define NAMEDFSEL_NAMES_CHUNK 0x2806
- // #define NAMEDESEL_NAMES_CHUNK 0x2807
- // #define NAMEDSEL_STRING_CHUNK 0x2809
- // #define NAMEDSEL_ID_CHUNK 0x2810
- // #define VSELSET_CHUNK 0x2845
- #define TAB_SIZE_CHUNK 0x2840
- #define FSEL_CHUNK 0x2850
- #define ESEL_CHUNK 0x2860
- #define CURPART_CHUNK 0x2870
- #define PARTS_CHUNK 0x2880
- // static int namedSelID[] = { NAMEDVSEL_NAMES_CHUNK, NAMEDESEL_NAMES_CHUNK, NAMEDFSEL_NAMES_CHUNK, NAMEDFSEL_NAMES_CHUNK, NAMEDFSEL_NAMES_CHUNK };
- // Fix these up, they are for saving/loading modifier scene data
- IOResult BSDSModifier::Save(ISave *isave) {
- IOResult res;
- ULONG nb;
- Modifier::Save(isave);
- isave->BeginChunk(VERSION_CHUNKID);
- res = isave->Write(¤tVersion, sizeof(int), &nb);
- isave->EndChunk();
- DWORD flags = ExportFlags();
- isave->BeginChunk(FLAGS_CHUNKID);
- res = isave->Write(&flags, sizeof(DWORD), &nb);
- isave->EndChunk();
- return res;
- }
- IOResult BSDSModifier::Load(ILoad *iload) {
- IOResult res;
- ULONG nb;
- int version = 1;
- DWORD flags;
- Modifier::Load(iload);
- while (IO_OK == (res = iload->OpenChunk())) {
- switch (iload->CurChunkID()) {
- case VERSION_CHUNKID:
- iload->Read(&version, sizeof(version), &nb);
- break;
- case FLAGS_CHUNKID:
- iload->Read(&flags, sizeof(DWORD), &nb);
- ImportFlags(flags);
- break;
- }
- iload->CloseChunk();
- if (res != IO_OK) return res;
- }
- return IO_OK;
- }
- IOResult BSDSModifier::SaveLocalData(ISave *isave, LocalModData *ld) {
- BSDSData *d = (BSDSData*)ld;
- ULONG nb;
- int tabSize = d->bodyParts.Count();
- isave->BeginChunk(TAB_SIZE_CHUNK);
- isave->Write(&tabSize, sizeof(int), &nb);
- isave->EndChunk();
- /*isave->BeginChunk(ESEL_CHUNK);
- for (int i = 0; i < d->edgeSel.Count(); i++) {
- d->edgeSel[i].Save(isave);
- }
- isave->EndChunk();*/
- isave->BeginChunk(FSEL_CHUNK);
- for (int i = 0; i < d->faceSel.Count(); i++) {
- d->faceSel[i].Save(isave);
- }
- isave->EndChunk();
- isave->BeginChunk(CURPART_CHUNK);
- isave->Write(&d->currentPartition, sizeof(int), &nb);
- isave->EndChunk();
- isave->BeginChunk(PARTS_CHUNK);
- for (int i = 0; i < tabSize; i++) {
- wstring temp = d->bodyParts[i].GetGameName();
- int selectLevel = d->bodyParts[i].selLevel;
- wstring tempFlag = d->bodyParts[i].currentSlot;
- isave->WriteWString(temp.c_str());
- isave->Write(&selectLevel, sizeof(int), &nb);
- isave->WriteWString(tempFlag.c_str());
- }
- isave->EndChunk();
- return IO_OK;
- }
- IOResult BSDSModifier::LoadLocalData(ILoad *iload, LocalModData **pld) {
- BSDSData *d = new BSDSData;
- ULONG nb = 0;
- *pld = d;
- IOResult res;
- while (IO_OK == (res = iload->OpenChunk())) {
- switch (iload->CurChunkID()) {
- case TAB_SIZE_CHUNK:
- int size;
- iload->Read(&size, sizeof(int), &nb);
- d->bodyParts.SetCount(size);
- // d->edgeSel.SetCount(size);
- d->faceSel.SetCount(size);
- break;
- /*case ESEL_CHUNK:
- for (int i = 0; i < d->edgeSel.Count(); i++) {
- BitArray temp;
- temp.Load(iload);
- d->edgeSel[i] = temp;
- }
- break;*/
- case FSEL_CHUNK:
- for (int i = 0; i < d->faceSel.Count(); i++) {
- BitArray temp;
- temp.Load(iload);
- d->faceSel[i] = temp;
- }
- break;
- case CURPART_CHUNK:
- iload->Read(&d->currentPartition, sizeof(int), &nb);
- break;
- case PARTS_CHUNK:
- for (int i = 0; i<d->bodyParts.Count(); i++) {
- TCHAR *buffer1;
- TCHAR *buffer2;
- int selectLevel;
- res = iload->ReadWStringChunk(&buffer1);
- res = iload->Read(&selectLevel, sizeof(int), &nb);
- res = iload->ReadWStringChunk(&buffer2);
- wstring temp(buffer1);
- wstring tempFlag(buffer2);
- DismemberPartition newPart(temp, selectLevel, tempFlag);
- d->bodyParts[i] = newPart;
- }
- }
- iload->CloseChunk();
- if (res != IO_OK) return res;
- }
- LocalDataChanged();
- return IO_OK;
- }
- //-------------------------------- Window Procs ----------------------------------
- void BSDSModifier::SetEnableStates() {
- if (!BSDSDesc.NumParamMaps()) return;
- IParamMap2 *pmap = BSDSDesc.GetParamMap(ms_map_main);
- if (!pmap) return;
- HWND hWnd = pmap->GetHWnd();
- if (!hWnd) return;
- theBSDSModifierMainDlgProc.SetEnables(hWnd);
- }
- void BSDSModifierMainDlgProc::SetEnables(HWND hParams) {
- if (!mod) return;
- int nPart, selLevel;
- BSDSData *d = mod->GetModifierData();
- if (!d) {
- selLevel = SEL_OBJECT;
- nPart = 1;
- }
- else {
- selLevel = d->bodyParts[d->currentPartition].selLevel;
- nPart = d->bodyParts.Count();
- }
- // int selLevel = d->bodyParts[d->currentPartition].selLevel;
- ICustButton *but;
- ISpinnerControl *spin;
- int nSub = mod->ip->GetSubObjectLevel();
- bool subSel = (nSub != 0);
- bool obj = (selLevel == SEL_OBJECT) ? TRUE : FALSE;
- // bool vert = (selLevel == SEL_VERTEX) ? TRUE : FALSE;
- // bool edge = (selLevel == SEL_EDGE) ? TRUE : FALSE;
- bool poly = (selLevel == SEL_POLY) ? TRUE : FALSE;
- bool face = (selLevel == SEL_FACE) || (selLevel == SEL_ELEMENT) || poly ? TRUE : FALSE;
- EnableWindow(GetDlgItem(hParams, IDC_MS_SEL_BYVERT), subSel && (/*edge || */face));
- // EnableWindow (GetDlgItem (hParams, IDC_MS_IGNORE_BACKFACES), subSel&&(edge||face));
- EnableWindow(GetDlgItem(hParams, IDC_MS_IGNORE_VISEDGE), subSel&&poly);
- EnableWindow(GetDlgItem(hParams, IDC_MS_PLANAR_TEXT), subSel&&poly);
- spin = GetISpinner(GetDlgItem(hParams, IDC_MS_PLANARSPINNER));
- spin->Enable(subSel&&poly);
- ReleaseISpinner(spin);
- EnableWindow(GetDlgItem(hParams, IDC_MS_IGNORE_BACKFACES), subSel);
- EnableWindow(GetDlgItem(hParams, IDC_MS_SELBYMAT_BOX), subSel&&face);
- EnableWindow(GetDlgItem(hParams, IDC_MS_SELBYMAT_TEXT), subSel&&face);
- but = GetICustButton(GetDlgItem(hParams, IDC_MS_SELBYMAT));
- but->Enable(subSel&&face);
- ReleaseICustButton(but);
- spin = GetISpinner(GetDlgItem(hParams, IDC_MS_MATIDSPIN));
- spin->Enable(subSel&&face);
- ReleaseISpinner(spin);
- // int npart = d->bodyParts.Count();
- mDelPart->Enable((nPart > 1) ? TRUE : FALSE);
- but = GetICustButton(GetDlgItem(hParams, IDC_MS_SELUNUSED));
- but->Enable(subSel);
- ReleaseICustButton(but);
- /*but = GetICustButton(GetDlgItem(hParams, IDC_MS_FIXDUPL));
- but->Enable(subSel);
- ReleaseICustButton(but);*/
- }
- INT_PTR BSDSModifierMainDlgProc::DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
- if (!mod) return FALSE;
- BSDSData *d = mod->GetModifierData();
- DismemberPartition tempInit;
- ICustToolbar *iToolbar;
- ICustButton *but;
- int matid;
- int nParts;
- int nActive;
- int objLevel;
- codeproject::bimap<wstring, int>::iterator itr;
- switch (msg) {
- case WM_INITDIALOG:
- // ListBox Game UI Control
- gameList.init(GetDlgItem(hWnd, IDC_CB_GAMETYPE));
- for (const EnumLookupType *gameFlag = GameFlags; gameFlag->name != NULL; ++gameFlag) {
- gameList.add(gameFlag->name);
- }
- gameList.select(1);
- // ListBox BodyPartUI Control
- /*dismemberList.init(GetDlgItem(hWnd, IDC_CB_BODYPART));
- for (itr = tempInit.slots.begin(); itr != tempInit.slots.end(); ++itr) {
- dismemberList.add(itr->first.c_str());
- }
- dismemberList.SelectString(tempInit.currentSlot.c_str());*/
- nParts = 1; // d->bodyParts.Count();
- nActive = 0; // d->currentPartition;
- objLevel = SEL_OBJECT; // d->bodyParts[d->currentPartition].selLevel;
- EnableWindow(GetDlgItem(hWnd, IDC_MS_PARTITION), TRUE);
- mActivePart = GetISpinner(GetDlgItem(hWnd, IDC_MS_PARTSPIN));
- mActivePart->LinkToEdit(GetDlgItem(hWnd, IDC_MS_PARTITION), EDITTYPE_POS_INT);
- mActivePart->SetValue(nActive, 0);
- mActivePart->SetLimits(0, nParts - 1, TRUE);
- mActivePart->SetAutoScale(FALSE);
- mActivePart->SetScale(1);
- mActivePart->SetResetValue(0);
- mAddPart = GetICustButton(GetDlgItem(hWnd, IDC_MS_ADDPART));
- #if VERSION_3DSMAX < ((10000<<16)+(24<<8)+0) // Version 7
- mAddPart->SetTooltip(TRUE, "Create New Partition");
- #endif
- mAddPart->SetImage(theBSDSPartImageHandler.LoadImages(), 0, 2, 0, 2, 16, 16);
- mDelPart = GetICustButton(GetDlgItem(hWnd, IDC_MS_DELPART));
- #if VERSION_3DSMAX < ((10000<<16)+(24<<8)+0) // Version 7
- mDelPart->SetTooltip(TRUE, "Delete Active Partition");
- #endif
- mDelPart->SetImage(theBSDSPartImageHandler.LoadImages(), 1, 3, 1, 3, 16, 16);
- iToolbar = GetICustToolbar(GetDlgItem(hWnd, IDC_MS_SELTYPE));
- iToolbar->SetImage(theBSDSImageHandler.LoadImages());
- // iToolbar->AddTool(ToolButtonItem(CTB_CHECKBUTTON,0,5,0,5,24,23,24,23,IDC_SELVERTEX));
- // iToolbar->AddTool(ToolButtonItem(CTB_CHECKBUTTON,1,6,1,6,24,23,24,23,IDC_SELEDGE));
- iToolbar->AddTool(ToolButtonItem(CTB_CHECKBUTTON, 2, 7, 2, 7, 24, 23, 24, 23, IDC_SELFACE));
- iToolbar->AddTool(ToolButtonItem(CTB_CHECKBUTTON, 3, 8, 3, 8, 24, 23, 24, 23, IDC_SELPOLY));
- iToolbar->AddTool(ToolButtonItem(CTB_CHECKBUTTON, 4, 9, 4, 9, 24, 23, 24, 23, IDC_SELELEMENT));
- ReleaseICustToolbar(iToolbar);
- #if VERSION_3DSMAX < ((10000<<16)+(24<<8)+0) // Version 11+
- but = GetICustButton(GetDlgItem(hWnd, IDC_MS_SELUNUSED));
- but->SetTooltip(TRUE, "Select unused faces into active partition");
- ReleaseICustButton(but);
- but = GetICustButton(GetDlgItem(hWnd, IDC_MS_FIXDUPL));
- but->SetTooltip(TRUE, "Remove duplicate faces from partitions");
- ReleaseICustButton(but);
- #endif
- UpdateSelLevelDisplay(hWnd);
- SetEnables(hWnd);
- break;
- case WM_NCDESTROY:
- if (mActivePart) {
- ReleaseISpinner(mActivePart);
- mActivePart = NULL;
- }
- if (mAddPart) {
- ReleaseICustButton(mAddPart);
- mAddPart = NULL;
- }
- if (mDelPart) {
- ReleaseICustButton(mDelPart);
- mDelPart = NULL;
- }
- break;
- case WM_UPDATE_CACHE:
- mod->UpdateCache((TimeValue)wParam);
- break;
- case CC_SPINNER_CHANGE:
- switch (LOWORD(wParam)) {
- case IDC_MS_PARTSPIN:
- if (d) {
- int idx = mActivePart->GetIVal();
- d->currentPartition = idx;
- mod->LocalDataChanged();
- mod->ip->SetSubObjectLevel(d->bodyParts[d->currentPartition].selLevel);
- }
- break;
- }
- break;
- case WM_CUSTEDIT_ENTER:
- switch (LOWORD(wParam)) {
- case IDC_MS_PARTITION:
- if (d){
- int idx = mActivePart->GetIVal();
- d->currentPartition = idx;
- mod->ip->SetSubObjectLevel(d->bodyParts[d->currentPartition].selLevel);
- }
- break;
- }
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_CB_GAMETYPE:
- if (HIWORD(wParam) == CBN_SELCHANGE) {
- d->bodyParts[d->currentPartition].thisGame = DismemberPartition::BethesdaGame (gameList.selection());
- d->bodyParts[d->currentPartition].configureMap();
- // dismemberList.Reset();
- /*for (itr = d->bodyParts[d->currentPartition].slots.begin(); itr != d->bodyParts[d->currentPartition].slots.end(); ++itr) {
- dismemberList.add(itr->first.c_str());
- }
- dismemberList.SelectString(d->bodyParts[d->currentPartition].currentSlot.c_str());*/
- mod->LocalDataChanged();
- // mod->NotifyDependents(FOREVER, PART_ALL, REFMSG_NUM_SUBOBJECTTYPES_CHANGED);
- }
- break;
- case IDC_CB_BODYPART:
- if (HIWORD(wParam) == CBN_SELCHANGE) {
- // d->bodyParts[d->currentPartition].currentSlot = dismemberList.GetStringSelection();
- mod->LocalDataChanged();
- // mod->NotifyDependents(FOREVER, PART_ALL, REFMSG_NUM_SUBOBJECTTYPES_CHANGED);
- }
- case IDC_MS_ADDPART:
- if (mActivePart) {
- if (d) {
- int idx = d->AddPartition();
- nParts = d->bodyParts.Count();
- mod->ip->SetSubObjectLevel(d->bodyParts[d->currentPartition].selLevel);
- mActivePart->SetLimits(0, nParts - 1, TRUE);
- mActivePart->SetValue(idx, TRUE);
- mod->LocalDataChanged();
- // mod->NotifyDependents(FOREVER, PART_ALL, REFMSG_NUM_SUBOBJECTTYPES_CHANGED);
- }
- }
- break;
- case IDC_MS_DELPART:
- if (mActivePart) {
- if (d) {
- int idx = mActivePart->GetIVal();
- d->RemovePartition(idx);
- mod->ip->SetSubObjectLevel(d->bodyParts[d->currentPartition].selLevel);
- nParts = d->bodyParts.Count();
- mActivePart->SetLimits(0, nParts, TRUE);
- mActivePart->SetValue(d->currentPartition, TRUE);
- mod->LocalDataChanged();
- // mod->NotifyDependents(FOREVER, PART_ALL, REFMSG_NUM_SUBOBJECTTYPES_CHANGED);
- }
- }
- break;
- /*case IDC_MS_FIXDUPL:
- mod->FixDuplicates();
- break;*/
- case IDC_MS_SELUNUSED:
- mod->SelectUnused();
- break;
- case IDC_MS_SELBYMAT:
- mod->pblock->GetValue(ms_matid, t, matid, FOREVER);
- mod->SelectByMatID(matid - 1);
- break;
- case IDC_SELFACE:
- if (d->bodyParts[d->currentPartition].selLevel == SEL_FACE) {
- mod->ip->SetSubObjectLevel(SEL_OBJECT);
- }
- else {
- mod->ip->SetSubObjectLevel(SEL_FACE);
- }
- /*if (d->bodyParts[d->currentPartition].selLevel != SEL_FACE) {
- d->bodyParts[d->currentPartition].selLevel = SEL_FACE;
- mod->ip->SetSubObjectLevel(SEL_FACE);
- }
- else {
- if (mod->ip->GetSubObjectLevel() != 0)
- mod->ip->SetSubObjectLevel(0);
- else
- mod->ip->SetSubObjectLevel(d->bodyParts[d->currentPartition].selLevel);
- }
- UpdateWindow(hWnd);*/
- break;
- case IDC_SELPOLY:
- if (d->bodyParts[d->currentPartition].selLevel != SEL_POLY) {
- d->bodyParts[d->currentPartition].selLevel = SEL_POLY;
- mod->ip->SetSubObjectLevel(d->bodyParts[d->currentPartition].selLevel);
- }
- else {
- if (mod->ip->GetSubObjectLevel() != 0)
- mod->ip->SetSubObjectLevel(0);
- else
- mod->ip->SetSubObjectLevel(d->bodyParts[d->currentPartition].selLevel);
- }
- UpdateWindow(hWnd);
- break;
- case IDC_SELELEMENT:
- if (d->bodyParts[d->currentPartition].selLevel != SEL_ELEMENT) {
- d->bodyParts[d->currentPartition].selLevel = SEL_ELEMENT;
- mod->ip->SetSubObjectLevel(d->bodyParts[d->currentPartition].selLevel);
- }
- else {
- if (mod->ip->GetSubObjectLevel() != 0)
- mod->ip->SetSubObjectLevel(0);
- else
- mod->ip->SetSubObjectLevel(d->bodyParts[d->currentPartition].selLevel);
- }
- UpdateWindow(hWnd);
- break;
- }
- break;
- case WM_NOTIFY:
- if (((LPNMHDR)lParam)->code != TTN_NEEDTEXT) break;
- LPTOOLTIPTEXT lpttt;
- lpttt = (LPTOOLTIPTEXT)lParam;
- switch (lpttt->hdr.idFrom) {
- //case IDC_SELVERTEX:
- // lpttt->lpszText = GetString (IDS_RB_VERTEX);
- // break;
- //case IDC_SELEDGE:
- // lpttt->lpszText = GetString (IDS_RB_EDGE);
- // break;
- case IDC_SELFACE:
- lpttt->lpszText = GetString(IDS_RB_FACE);
- break;
- case IDC_SELPOLY:
- lpttt->lpszText = GetString(IDS_EM_POLY);
- break;
- case IDC_SELELEMENT:
- lpttt->lpszText = GetString(IDS_EM_ELEMENT);
- break;
- }
- break;
- default: return FALSE;
- }
- return TRUE;
- }
- //-------------------------------- BSDSData Functions ----------------------------------
- LocalModData *BSDSData::Clone() {
- BSDSData *d = new BSDSData;
- d->currentPartition = currentPartition;
- for (int i = 0; i < bodyParts.Count(); i++) {
- d->bodyParts.Append(1, &bodyParts[i]);
- }
- /*for (int i = 0; i < bodyParts.Count(); i++) {
- d->edgeSel.Append(1, &edgeSel[i]);
- }*/
- for (int i = 0; i < bodyParts.Count(); i++) {
- d->faceSel.Append(1, &faceSel[i]);
- }
- return d;
- }
- BSDSData::BSDSData(Mesh &mesh) {
- held = FALSE; this->mesh = NULL; temp = NULL;
- currentPartition = 0;
- BitArray tempEdge(mesh.edgeSel);
- BitArray tempFace(mesh.faceSel);
- faceSel.Append(1, &tempEdge);
- // edgeSel.Append(1, &tempFace);
- DismemberPartition test;
- bodyParts.Append(1, &test);
- }
- BSDSData::BSDSData(){
- held = FALSE;
- mesh = NULL;
- temp = NULL;
- BitArray empty;
- DismemberPartition first;
- bodyParts.Append(1, &first);
- currentPartition = 0;
- // edgeSel.Append(1, &empty);
- faceSel.Append(1, &empty);
- }
- void BSDSData::SynchBitArrays() {
- if (!mesh) return;
- if (faceSel[currentPartition].GetSize() != mesh->getNumFaces()) faceSel[currentPartition].SetSize(mesh->getNumFaces(), TRUE);
- // if (edgeSel[currentPartition].GetSize() != mesh->getNumFaces() * 3) edgeSel[currentPartition].SetSize(mesh->getNumFaces() * 3, TRUE);
- }
- AdjEdgeList *BSDSData::GetAdjEdgeList() {
- if (!mesh) return NULL;
- if (!temp) temp = new MeshTempData;
- temp->SetMesh(mesh);
- return temp->AdjEList();
- }
- AdjFaceList *BSDSData::GetAdjFaceList() {
- if (!mesh) return NULL;
- if (!temp) temp = new MeshTempData;
- temp->SetMesh(mesh);
- return temp->AdjFList();
- }
- void BSDSData::SetCache(Mesh &mesh) {
- if (this->mesh) delete this->mesh;
- this->mesh = new Mesh(mesh);
- if (temp) temp->Invalidate(PART_TOPO);
- SynchBitArrays();
- }
- void BSDSData::FreeCache() {
- if (mesh) delete mesh;
- mesh = NULL;
- if (temp) delete temp;
- temp = NULL;
- }
- void BSDSData::SetFaceSel(BitArray &set, BSDSModifier *imod, TimeValue t) {
- BSDSModifier *mod = imod;
- if (theHold.Holding()) theHold.Put(new SelectRestore(mod, this/*, SEL_FACE*/));
- if (mesh) {
- mesh->faceSel = set;
- faceSel[currentPartition] = set;
- }
- }
- /*void BSDSData::SetEdgeSel(BitArray set, BSDSModifier *imod, TimeValue t) {
- BSDSModifier *mod = (BSDSModifier *)imod;
- if (theHold.Holding()) theHold.Put(new SelectRestore(mod, this, SEL_EDGE));
- edgeSel[currentPartition] = set;
- if (mesh) mesh->edgeSel = set;
- }*/
- void BSDSData::SelVertByFace() {
- DbgAssert(mesh);
- if (!mesh) return;
- BitArray vertSel = mesh->vertSel;
- BitArray faceSel = faceSel[currentPartition];
- for (int i = 0; i<mesh->getNumFaces(); i++) {
- if (!faceSel[i]) continue;
- for (int j = 0; j<3; j++) vertSel.Set(mesh->faces[i].v[j]);
- }
- }
- /*void BSDSData::SelVertByEdge() {
- DbgAssert(mesh);
- if (!mesh) return;
- BitArray vertSel = mesh->vertSel;
- for (int i = 0; i<mesh->getNumFaces(); i++) {
- for (int j = 0; j<3; j++) {
- if (!edgeSel[currentPartition][i * 3 + j]) continue;
- vertSel.Set(mesh->faces[i].v[j], TRUE);
- vertSel.Set(mesh->faces[i].v[(j + 1) % 3], TRUE);
- }
- }
- }*/
- void BSDSData::SelFaceByVert() {
- DbgAssert(mesh);
- if (!mesh) return;
- BitArray vertSel = mesh->vertSel;
- BitArray faceSel = faceSel[currentPartition];
- for (int i = 0; i<mesh->getNumFaces(); i++) {
- for (int j = 0; j<3; j++) if (vertSel[mesh->faces[i].v[j]]) { faceSel.Set(i); break; }
- }
- }
- void BSDSData::SelFaceByEdge() {
- DbgAssert(mesh);
- if (!mesh) return;
- BitArray edgeSel = edgeSel[currentPartition];
- BitArray faceSel = faceSel[currentPartition];
- for (int i = 0; i<mesh->getNumFaces(); i++) {
- for (int j = 0; j<3; j++) if (edgeSel[i * 3 + j]) { faceSel.Set(i); break; }
- }
- }
- void BSDSData::SelPolygonByVert(float thresh, int igVis) {
- DbgAssert(mesh);
- if (!mesh) return;
- BitArray vertSel = mesh->vertSel;
- BitArray faceSel = faceSel[currentPartition];
- BitArray nfsel;
- nfsel.SetSize(mesh->getNumFaces());
- for (int i = 0; i<mesh->getNumFaces(); i++) {
- for (int j = 0; j<3; j++) if (vertSel[mesh->faces[i].v[j]])
- {
- mesh->PolyFromFace(i, nfsel, thresh, igVis, GetAdjFaceList()); break;
- }
- }
- faceSel |= nfsel;
- }
- void BSDSData::SelPolygonByEdge(float thresh, int igVis) {
- DbgAssert(mesh);
- if (!mesh) return;
- BitArray edgeSel = edgeSel[currentPartition];
- BitArray faceSel = faceSel[currentPartition];
- BitArray nfsel;
- nfsel.SetSize(mesh->getNumFaces());
- for (int i = 0; i<mesh->getNumFaces(); i++) {
- for (int j = 0; j<3; j++) if (edgeSel[i * 3 + j])
- {
- mesh->PolyFromFace(i, nfsel, thresh, igVis, GetAdjFaceList()); break;
- }
- }
- faceSel |= nfsel;
- }
- /*void BSDSData::SelElementByVert() {
- DbgAssert(mesh);
- if (!mesh) return;
- BitArray vertSel = edgeSel[currentPartition];
- BitArray faceSel = faceSel[currentPartition];
- BitArray nfsel;
- nfsel.SetSize(mesh->getNumFaces());
- for (int i = 0; i<mesh->getNumFaces(); i++) {
- for (int j = 0; j<3; j++) if (vertSel[mesh->faces[i].v[j]])
- {
- mesh->ElementFromFace(i, nfsel, GetAdjFaceList()); break;
- }
- }
- faceSel |= nfsel;
- }*/
- void BSDSData::SelElementByEdge() {
- DbgAssert(mesh);
- if (!mesh) return;
- BitArray edgeSel = edgeSel[currentPartition];
- BitArray faceSel = faceSel[currentPartition];
- BitArray nfsel;
- nfsel.SetSize(mesh->getNumFaces());
- for (int i = 0; i<mesh->getNumFaces(); i++) {
- for (int j = 0; j<3; j++) if (edgeSel[i * 3 + j])
- {
- mesh->ElementFromFace(i, nfsel, GetAdjFaceList()); break;
- }
- }
- faceSel |= nfsel;
- }
- void BSDSData::SelEdgeByVert() {
- DbgAssert(mesh);
- if (!mesh) return;
- BitArray vertSel = mesh->vertSel;
- BitArray edgeSel = edgeSel[currentPartition];
- for (int i = 0; i<mesh->getNumFaces(); i++) {
- for (int j = 0; j<3; j++) {
- if (vertSel[mesh->faces[i].v[j]]) edgeSel.Set(i * 3 + j);
- if (vertSel[mesh->faces[i].v[(j + 1) % 3]]) edgeSel.Set(i * 3 + j);
- }
- }
- }
- void BSDSData::SelEdgeByFace() {
- DbgAssert(mesh);
- if (!mesh) return;
- BitArray edgeSel = edgeSel[currentPartition];
- BitArray faceSel = faceSel[currentPartition];
- for (int i = 0; i<mesh->getNumFaces(); i++) {
- if (!faceSel[i]) continue;
- for (int j = 0; j<3; j++) edgeSel.Set(i * 3 + j);
- }
- }
- // Unfixed version of code, possibly not needed anymore
- /*void BSDSData::SetActivePartition(int partition)
- {
- currentPartition = partition;
- while (flags.Count() <= partition) {
- BSDSPartitionData flag;
- flag.bodyPart = BP_TORSO;
- flag.partFlag = 1;
- flag.selLevel = SEL_FACE;
- flags.Append(1, &flag);
- }
- BitArray empty;
- while (vselSet.Count() <= partition){
- vselSet.AppendSet(empty);
- }
- while (fselSet.Count() <= partition){
- fselSet.AppendSet(empty);
- }
- while (eselSet.Count() <= partition){
- eselSet.AppendSet(empty);
- }
- }*/
- void BSDSData::RemovePartition(int num)
- {
- if (num < bodyParts.Count() && bodyParts.Count() > 1)
- {
- bodyParts.Delete(num, 1);
- // edgeSel.Delete(num, 1);
- faceSel.Delete(num, 1);
- if (num >= bodyParts.Count())
- currentPartition = 0;
- }
- }
- int BSDSData::AddPartition() {
- DismemberPartition add;
- BitArray empty;
- // edgeSel.Append(1, &empty);
- faceSel.Append(1, &empty);
- bodyParts.Append(1, &add);
- currentPartition += 1;
- return currentPartition;
- }
- BitArray BSDSData::GetUnused()
- {
- SynchBitArrays();
- BitArray toSelect;
- toSelect.SetSize(faceSel.Count());
- toSelect.SetAll();
- Tab<BitArray>inverses;
- for (int i = 0; i < faceSel.Count(); i++) {
- BitArray temp = faceSel[i];
- temp.Reverse();
- inverses.Append(1, &temp);
- }
- if (inverses.Count() > 0) {
- for (int i = 0; i < inverses.Count(); i++) {
- toSelect &= inverses[i];
- }
- }
- return toSelect;
- }
- /*SelectRestore::SelectRestore(BSDSModifier *m, BSDSData *data, int sLevel) {
- mod = m;
- level = sLevel;
- d = data;
- d->held = TRUE;
- switch (level) {
- case SEL_OBJECT: DbgAssert(0); break;
- // case SEL_VERTEX: break;
- case SEL_EDGE:
- usel = d->edgeSel[sLevel]; break;
- default:
- usel = d->faceSel[sLevel]; break;
- }
- }*/
- SelectRestore::SelectRestore(BSDSModifier *m, BSDSData *data) {
- mod = m;
- d = data;
- level = d->bodyParts[d->currentPartition].selLevel;
- d->held = TRUE;
- switch (level) {
- case SEL_OBJECT: DbgAssert(0); break;
- default:
- usel = d->faceSel[d->currentPartition]; break;
- }
- //SelectRestore::SelectRestore(m, d, d->bodyParts[d->currentPartition].selLevel);
- }
- void SelectRestore::Restore(int isUndo) {
- if (isUndo) {
- switch (level) {
- // case SEL_VERTEX: break;
- case SEL_FACE:
- case SEL_POLY:
- case SEL_ELEMENT:
- rsel = d->faceSel[d->currentPartition]; break;
- /*case SEL_EDGE:
- rsel = d->edgeSel[d->currentPartition]; break;*/
- }
- }
- switch (level) {
- // case SEL_VERTEX: break;
- case SEL_FACE:
- case SEL_POLY:
- case SEL_ELEMENT:
- d->faceSel[d->currentPartition] = usel; break;
- /*case SEL_EDGE:
- d->edgeSel[d->currentPartition] = usel; break;*/
- }
- mod->LocalDataChanged();
- }
- void SelectRestore::Redo() {
- switch (level) {
- // case SEL_VERTEX: break;
- case SEL_FACE:
- case SEL_POLY:
- case SEL_ELEMENT:
- d->faceSel[d->currentPartition] = rsel; break;
- /*case SEL_EDGE:
- d->edgeSel[d->currentPartition] = rsel; break;*/
- }
- mod->LocalDataChanged();
- }
- void BSDSModifier::SetNumSelLabel() {
- TSTR buf;
- int num = 0;
- int which = 0;
- BSDSData* d = (BSDSData*)GetModifierData();
- if (!BSDSDesc.NumParamMaps()) return;
- IParamMap2 *pmap = BSDSDesc.GetParamMap(ms_map_main);
- if (!pmap) return;
- HWND hParams = pmap->GetHWnd();
- if (!hParams) return;
- // int selLevel = SEL_OBJECT;
- // Tab<IBSDismemberSkinModifierData*> list = GetModifierData();
- // for (int i = 0; i<list.Count(); i++) {
- // BSDSData *meshData = (BSDSData *)list[i];
- if (!d) return;
- // selLevel = meshData->GetSelectionLevel();
- switch (d->bodyParts[d->currentPartition].selLevel) {
- /*case SEL_VERTEX:
- num += meshData->GetVertSel().NumberSet();
- if (meshData->GetVertSel().NumberSet() == 1) {
- for (which = 0; which<meshData->GetVertSel().GetSize(); which++) if (meshData->GetVertSel()[which]) break;
- }*/
- break;
- case SEL_FACE:
- case SEL_POLY:
- case SEL_ELEMENT:
- num += d->faceSel[d->currentPartition].NumberSet();
- if (d->faceSel[d->currentPartition].NumberSet() == 1) {
- for (which = 0; which<d->faceSel[d->currentPartition].GetSize(); which++) if (d->faceSel[d->currentPartition][which]) break;
- }
- break;
- /*case SEL_EDGE:
- num += d->edgeSel[d->currentPartition].NumberSet();
- if (d->edgeSel[d->currentPartition].NumberSet() == 1) {
- for (which = 0; which<d->edgeSel[d->currentPartition].GetSize(); which++) if (d->edgeSel[d->currentPartition][which]) break;
- }
- break;*/
- }
- // }
- switch (d->bodyParts[d->currentPartition].selLevel) {
- /*case SEL_VERTEX:
- if (num == 1) buf.printf(GetString(IDS_EM_WHICHVERTSEL), which + 1);
- else buf.printf(GetString(IDS_RB_NUMVERTSELP), num);
- break;*/
- case SEL_FACE:
- case SEL_POLY:
- case SEL_ELEMENT:
- if (num == 1) buf.printf(GetString(IDS_EM_WHICHFACESEL), which + 1);
- else buf.printf(GetString(IDS_RB_NUMFACESELP), num);
- break;
- /*case SEL_EDGE:
- if (num == 1) buf.printf(GetString(IDS_EM_WHICHEDGESEL), which + 1);
- else buf.printf(GetString(IDS_RB_NUMEDGESELP), num);
- break;*/
- case SEL_OBJECT:
- buf = GetString(IDS_EM_OBJECT_SEL);
- break;
- }
- SetDlgItemText(hParams, IDC_MS_NUMBER_SEL, buf);
- }
- void BSDSModifier::SelectUnused()
- {
- theHold.Begin();
- BSDSData *d = (BSDSData*)GetModifierData();
- if (!d->held) theHold.Put(new SelectRestore(this, d));
- d->faceSel[d->currentPartition] = d->GetUnused();
- theHold.Accept(GetString(IDS_RB_SELUNUSED));
- LocalDataChanged();
- ip->RedrawViews(ip->GetTime());
- }
- RefResult BSDSModifier::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
- PartID& partID, RefMessage message) {
- if ((message == REFMSG_CHANGE) && (hTarget == pblock)) {
- // if this was caused by a NotifyDependents from pblock, LastNotifyParamID()
- // will contain ID to update, else it will be -1 => inval whole rollout
- int pid = pblock->LastNotifyParamID();
- InvalidateDialogElement(pid);
- }
- return(REF_SUCCEED);
- }
- int BSDSModifier::NumSubObjTypes()
- {
- return 3;
- }
- ISubObjType *BSDSModifier::GetSubObjType(int i)
- {
- /*static bool initialized = false;
- if (!initialized)
- {
- initialized = true;
- // SOT_Vertex.SetName(GetString(IDS_RB_VERTEX));
- // SOT_Edge.SetName(GetString(IDS_RB_EDGE));
- SOT_Face.SetName(GetString(IDS_RB_FACE));
- GetString(IDS_EM_POLY);
- SOT_Poly.SetName(GetString(IDS_EM_POLY));
- SOT_Element.SetName(GetString(IDS_EM_ELEMENT));
- }
- switch (i)
- {
- case -1:
- if (GetSubObjectLevel() > 0)
- return GetSubObjType(GetSubObjectLevel() - 1);
- break;
- case 0:
- return &SOT_Vertex;
- case 1:
- return &SOT_Edge;
- case 2:
- return &SOT_Face;
- case 3:
- return &SOT_Poly;
- case 4:
- return &SOT_Element;
- }*/
- switch (i)
- {
- case -1:
- /*if (GetSubObjectLevel() > 0)
- return GetSubObjType(GetSubObjectLevel() - 1);*/
- break;
- case 0:
- return &SOT_Face;
- case 1:
- return &SOT_Poly;
- case 2:
- return &SOT_Element;
- }
- return NULL;
- // Old code
- /*BSDSData *d = (BSDSData*)GetModifierData();
- if (i >= subObjects.Count())
- return NULL;
- if (i < 0) {
- if (d->currentPartition > 0)
- return GetSubObjType(d->currentPartition - 1);
- return NULL;
- }
- return &subObjects[i];*/
- }
- void BSDSModifier::InvalidateDialogElement(int elem) {
- if (!pblock) return;
- if (!BSDSDesc.NumParamMaps()) return;
- IParamMap2 *pmap = BSDSDesc.GetParamMap(ms_map_main);
- if (pmap) pmap->Invalidate(elem);
- }
- // Get or Create the BSDismember Modifier
- Modifier *GetOrCreateBSDismemberSkin(INode *node)
- {
- Modifier *BSMod = GetBSDismemberSkin(node);
- if (BSMod)
- return BSMod;
- Object *pObj = node->GetObjectRef();
- IDerivedObject *pDerObj = NULL;
- if (pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID)
- pDerObj = dynamic_cast<IDerivedObject*>(pObj);
- else {
- pDerObj = CreateDerivedObject(pObj);
- }
- // Never ever do the following line, it spawns multiple DerivedObjects, each node should only have 1 Derived Object.
- // IDerivedObject *dobj = CreateDerivedObject(node->GetObjectRef());
- //create a BSDismemberment modifier and add it
- BSMod = (Modifier*)CreateInstance(OSM_CLASS_ID, BSDSMODIFIER_CLASS_ID);
- pDerObj->SetAFlag(A_LOCK_TARGET);
- pDerObj->AddModifier(BSMod);
- pDerObj->ClearAFlag(A_LOCK_TARGET);
- node->SetObjectRef(pDerObj);
- return BSMod;
- }
- Modifier *GetBSDismemberSkin(INode *node)
- {
- Object* pObj = node->GetObjectRef();
- if (!pObj) return NULL;
- while (pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID)
- {
- IDerivedObject* pDerObj = (IDerivedObject *)(pObj);
- int Idx = 0;
- while (Idx < pDerObj->NumModifiers())
- {
- // Get the modifier.
- Modifier* mod = pDerObj->GetModifier(Idx);
- if (mod->ClassID() == BSDSMODIFIER_CLASS_ID)
- return mod;
- Idx++;
- }
- pObj = pDerObj->GetObjRef();
- }
- return NULL;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement