Monday, 16 February 2015

Metasequoia 4 Plugins – part 6

I installed the latest Metasequoia (version 4.4.0) using the default path and it was installed in Program Files.

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.

Indexer

I modified the code to display the indices for only the selected vertices and faces.

//---------------------------------------------------------------------------
//
// 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;
}
view raw Indexer.cpp hosted with ❤ by GitHub

If you view the code at GitHub and click Revisions you can see which lines I added to the original code.

GitHub


I found some Metasequoia plugins at this site [link] which include source code that can be used for learning.

Plugins


prev | next | first

No comments:

Post a Comment