I changed the paths in the Project Property Pages for Debugging>Command and Build Events>Post-Build Event>Command Line accordingly.
The Post-Build Event>Command Line I used to copy the DLL to the Plugins folder now failed because of User Account Control (UAC) which requires administrator rights to copy to folders in Program Files.
I now use the following Command Line which uses Windows PowerShell to open another Windows PowerShell console with administrator rights and copy the DLL to the Plugins folder.
powershell.exe "Start-Process powershell.exe -verb runAs -windowstyle Hidden –ArgumentList 'cp $(TargetPath) ''$(ProgramFiles)\tetraface\Metasequoia4\Plugins\Station'''"
There are two single quotes surrounding $(ProgramFiles)\tetraface\Metasequoia4\Plugins\Station because of the space in “Program Files”.
UPDATE: May2015
I discovered I don't need administrator rights because in Windows 8.1 you should copy the plugins to the corresponding plugin type folders located at "C:\Users\<username>\AppData\Roaming\tetraface\Metasequoia4\Plugins\".
Create the folders if they do not exist first.
The Indexer plugin included in the SDK displays the indices for every vertex and face in an object.
I modified the code to display the indices for only the selected vertices and faces.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//--------------------------------------------------------------------------- | |
// | |
// Indexer | |
// | |
// Copyright(C) 2012-2013, tetraface Inc. | |
// | |
// | |
//--------------------------------------------------------------------------- | |
#define WIN32_LEAN_AND_MEAN | |
#include <windows.h> | |
#include <vector> | |
#include "MQBasePlugin.h" | |
HINSTANCE hInstance; | |
//--------------------------------------------------------------------------- | |
// DllMain | |
//--------------------------------------------------------------------------- | |
BOOL APIENTRY DllMain( HANDLE hModule, | |
DWORD ul_reason_for_call, | |
LPVOID lpReserved | |
) | |
{ | |
//ダイアログボックスの表示に必要なので、インスタンスを保存しておく | |
hInstance = (HINSTANCE)hModule; | |
//プラグインとしては特に必要な処理はないので、何もせずにTRUEを返す | |
return TRUE; | |
} | |
class IndexerPlugin : public MQStationPlugin | |
{ | |
public: | |
// コンストラクタ | |
IndexerPlugin(); | |
// プラグインIDを返す。 | |
virtual void GetPlugInID(DWORD *Product, DWORD *ID); | |
// プラグイン名を返す。 | |
virtual const char *GetPlugInName(void); | |
// ポップアップメニューに表示される文字列を返す。 | |
virtual const char *EnumString(void); | |
// アプリケーションの初期化 | |
virtual BOOL Initialize(); | |
// アプリケーションの終了 | |
virtual void Exit(); | |
// 表示・非表示切り替え要求 | |
virtual BOOL Activate(MQDocument doc, BOOL flag); | |
// 表示・非表示状態の返答 | |
virtual BOOL IsActivated(MQDocument doc); | |
// 描画時の処理 | |
virtual void OnDraw(MQDocument doc, MQScene scene, int width, int height); | |
// カレントオブジェクトの変更時 | |
virtual void OnUpdateObjectList(MQDocument doc); | |
protected: | |
// コールバックに対する実装部 | |
virtual bool ExecuteCallback(MQDocument doc, void *option); | |
private: | |
bool m_bVertIndex; | |
bool m_bFaceIndex; | |
}; | |
//--------------------------------------------------------------------------- | |
// GetPluginClass | |
// プラグインのベースクラスを返す | |
//--------------------------------------------------------------------------- | |
MQBasePlugin *GetPluginClass() | |
{ | |
static IndexerPlugin plugin; | |
return &plugin; | |
} | |
//--------------------------------------------------------------------------- | |
// IndexerPlugin::IndexerPlugin | |
// コンストラクタ | |
//--------------------------------------------------------------------------- | |
IndexerPlugin::IndexerPlugin() | |
{ | |
m_bVertIndex = false; | |
m_bFaceIndex = false; | |
} | |
//--------------------------------------------------------------------------- | |
// IndexerPlugin::GetPlugInID | |
// プラグインIDを返す。 | |
//--------------------------------------------------------------------------- | |
void IndexerPlugin::GetPlugInID(DWORD *Product, DWORD *ID) | |
{ | |
// プロダクト名(制作者名)とIDを、全部で64bitの値として返す | |
// 値は他と重複しないようなランダムなもので良い | |
*Product = 0x56A31D20; | |
*ID = 0x364AF702; | |
} | |
//--------------------------------------------------------------------------- | |
// IndexerPlugin::GetPlugInName | |
// プラグイン名を返す。 | |
//--------------------------------------------------------------------------- | |
const char *IndexerPlugin::GetPlugInName(void) | |
{ | |
// プラグイン名 | |
return "Indexer Copyright(C) 2012-2013, tetraface Inc."; | |
} | |
//--------------------------------------------------------------------------- | |
// IndexerPlugin::EnumString | |
// ボタンに表示される文字列を返す。 | |
//--------------------------------------------------------------------------- | |
const char *IndexerPlugin::EnumString(void) | |
{ | |
return "Indexer"; | |
} | |
//--------------------------------------------------------------------------- | |
// IndexerPlugin::Initialize | |
// アプリケーションの初期化 | |
//--------------------------------------------------------------------------- | |
BOOL IndexerPlugin::Initialize() | |
{ | |
return TRUE; | |
} | |
//--------------------------------------------------------------------------- | |
// IndexerPlugin::Exit | |
// アプリケーションの終了 | |
//--------------------------------------------------------------------------- | |
void IndexerPlugin::Exit() | |
{ | |
// Nothing to do. | |
// 特に何もしない | |
} | |
//--------------------------------------------------------------------------- | |
// SingleMovePlugin::Activate | |
// 表示・非表示切り替え要求 | |
//--------------------------------------------------------------------------- | |
BOOL IndexerPlugin::Activate(MQDocument doc, BOOL flag) | |
{ | |
m_bVertIndex = flag ? true : false; | |
m_bFaceIndex = flag ? true : false; | |
MQ_RefreshView(NULL); | |
return flag; | |
} | |
BOOL IndexerPlugin::IsActivated(MQDocument doc) | |
{ | |
return m_bVertIndex || m_bFaceIndex; | |
} | |
//--------------------------------------------------------------------------- | |
// IndexerPlugin::OnDraw | |
// 描画時の処理 | |
//--------------------------------------------------------------------------- | |
void IndexerPlugin::OnDraw(MQDocument doc, MQScene scene, int width, int height) | |
{ | |
static const int ch0[] = {1,3, 2,2, 2,-2, 1,-3, -1,-3, -2,-2, -2,2, -1,3, 1,3, INT_MIN,INT_MIN}; | |
static const int ch1[] = {0,3, 0,-3, INT_MIN,INT_MIN}; | |
static const int ch2[] = {-2,2, -1,3, 1,3, 2,2, 2,1, 1,0, -1,0, -2,-1, -2,-3, 2,-3, INT_MIN,INT_MIN}; | |
static const int ch3[] = {-2,2, -1,3, 1,3, 2,2, 2,1, 1,0, -1,0, 1,0, 2,-1, 2,-2, 1,-3, -1,-3, -2,-2, INT_MIN,INT_MIN}; | |
static const int ch4[] = {2,-1, -2,-1, -2,1, 0,3, 1,3, 1,-3, INT_MIN,INT_MIN}; | |
static const int ch5[] = {2,3, -2,3, -2,1, 1,1, 2,0, 2,-2, 1,-3, -1,-3, -2,-2, INT_MIN,INT_MIN}; | |
static const int ch6[] = {2,2, 1,3, -1,3, -2,2, -2,-2, -1,-3, 1,-3, 2,-2, 2,-1, 1,0, -2,-0, INT_MIN,INT_MIN}; | |
static const int ch7[] = {-2,3, 2,3, 0,-3, INT_MIN,INT_MIN}; | |
static const int ch8[] = {1,0, 2,1, 2,2, 1,3, -1,3, -2,2, -2,1, -1,0, -2,-1, -2,-2, -1,-3, 1,-3, 2,-2, 2,-1, 1,0, -1,0, INT_MIN,INT_MIN}; | |
static const int ch9[] = {2,1, 1,0, -1,0, -2,1, -2,2, -1,3, 1,3, 2,2, 2,-2, 1,-3, -1,-3, -2,-2, INT_MIN,INT_MIN}; | |
static const int *chara[10] = {ch0, ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9}; | |
if(m_bFaceIndex){ | |
int curidx = doc->GetCurrentObjectIndex(); | |
MQObject obj = (curidx >= 0) ? doc->GetObject(curidx) : NULL; | |
if(obj != NULL){ | |
MQObject draw = CreateDrawingObject(doc, DRAW_OBJECT_LINE); | |
draw->SetColor(MQColor(1,1,0)); | |
draw->SetColorValid(TRUE); | |
int fc = obj->GetFaceCount(); | |
for(int fi=0; fi<fc; fi++){ | |
if(!doc->IsSelectFace(curidx, fi)) continue; | |
int count = obj->GetFacePointCount(fi); | |
if(count > 0){ | |
MQPoint p(0,0,0); | |
std::vector<int> index(count); | |
obj->GetFacePointArray(fi, &(*index.begin())); | |
for(int j=0; j<count; j++){ | |
p += obj->GetVertex(index[j]); | |
} | |
p /= (float)count; | |
char str[16]; | |
sprintf_s(str, _countof(str), "%d", fi); | |
MQPoint sp = scene->Convert3DToScreen(p); | |
float spx = floor(sp.x+0.5f) + 0.01f; | |
float spy = floor(sp.y+0.5f) + 0.01f; | |
for(size_t s=0; str[s] != '\0'; s++){ | |
int n = str[s] - '0'; | |
for(int i=0; chara[n][i]!=INT_MIN; i+=2){ | |
MQPoint newvp = scene->ConvertScreenTo3D(MQPoint(spx+chara[n][i]+s*6, spy-chara[n][i+1], scene->GetFrontZ())); | |
int vi = draw->AddVertex(newvp); | |
if(i > 0){ | |
int index[2]; | |
index[0] = vi-1; | |
index[1] = vi; | |
draw->AddFace(2, index); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
if(m_bVertIndex){ | |
int curidx = doc->GetCurrentObjectIndex(); | |
MQObject obj = (curidx >= 0) ? doc->GetObject(curidx) : NULL; | |
if(obj != NULL){ | |
MQObject draw = CreateDrawingObject(doc, DRAW_OBJECT_LINE); | |
draw->SetColor(MQColor(0,1,1)); | |
draw->SetColorValid(TRUE); | |
int vc = obj->GetVertexCount(); | |
for(int vi=0; vi<vc; vi++){ | |
if(obj->GetVertexRefCount(vi) == 0) continue; | |
if (!doc->IsSelectVertex(curidx, vi)) continue; | |
MQPoint p = obj->GetVertex(vi); | |
char str[16]; | |
sprintf_s(str, _countof(str), "%d", vi); | |
MQPoint sp = scene->Convert3DToScreen(p); | |
float spx = floor(sp.x+0.5f) + 4.001f; | |
float spy = floor(sp.y+0.5f) + 0.001f; | |
for(size_t s=0; str[s] != '\0'; s++){ | |
int n = str[s] - '0'; | |
for(int i=0; chara[n][i]!=INT_MIN; i+=2){ | |
MQPoint newvp = scene->ConvertScreenTo3D(MQPoint(spx+chara[n][i]+s*6, spy-chara[n][i+1], scene->GetFrontZ())); | |
int vi = draw->AddVertex(newvp); | |
if(i > 0){ | |
int index[2]; | |
index[0] = vi-1; | |
index[1] = vi; | |
draw->AddFace(2, index); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
void IndexerPlugin::OnUpdateObjectList(MQDocument doc) | |
{ | |
if(m_bVertIndex || m_bFaceIndex){ | |
MQ_RefreshView(NULL); | |
} | |
} | |
bool IndexerPlugin::ExecuteCallback(MQDocument doc, void *option) | |
{ | |
return false; | |
} | |
If you view the code at GitHub and click Revisions you can see which lines I added to the original code.
I found some Metasequoia plugins at this site [link] which include source code that can be used for learning.
prev | next | first
No comments:
Post a Comment