This example demonstrates how to manually implement a tool operation item.
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
/* | |
* | |
* This example demonstrates how to manually implement a tool operation | |
* item. | |
* | |
*/ | |
#include <lxsdk/lx_mesh.hpp> | |
#include <lxsdk/lx_tool.hpp> | |
#include <lxsdk/lx_toolui.hpp> | |
#include <lxsdk/lx_vector.hpp> | |
#include <lxsdk/lxu_attributes.hpp> | |
#include <lxsdk/lxu_math.hpp> | |
#include <lxsdk/lxu_modifier.hpp> | |
#include <lxsdk/lxu_package.hpp> | |
#include <lxsdk/lx_layer.hpp> | |
#include <cmath> | |
static const char *sPackageName = "plane.tool.item"; | |
static const char *sToolOpName = "plane.tool.operation"; | |
static const char *sToolName = "plane.tool"; | |
static const char *sModifierName = "plane.tool.modifier"; | |
static const char *sAttrSize = "size"; | |
static LXtTextValueHint sHintMinZero[] = | |
{ | |
0, "%min", | |
-1, NULL | |
}; | |
class Package : | |
public CLxDefaultPackage | |
{ | |
public: | |
static void | |
initialize() | |
{ | |
CLxGenericPolymorph *srv = new CLxPolymorph<Package>; | |
srv->AddInterface(new CLxIfc_Package<Package>); | |
srv->AddInterface(new CLxIfc_StaticDesc<Package>); | |
lx::AddServer(sPackageName, srv); | |
} | |
LXxO_Package_SetupChannels // LxResult (ILxUnknownID addChan) | |
{ | |
CLxUser_AddChannel channel(addChan); | |
if(LXx_OK(channel.NewChannel(sAttrSize, LXsTYPE_DISTANCE))) | |
{ | |
channel.SetDefault(0.5, 0); | |
channel.SetHint(sHintMinZero); | |
} | |
if(LXx_OK(channel.NewChannel(LXsICHAN_TOOL_OBJ, LXsTYPE_OBJREF))) | |
{ | |
channel.SetInternal(); | |
} | |
return LXe_OK; | |
} | |
static LXtTagInfoDesc descInfo[]; | |
}; | |
LXtTagInfoDesc Package::descInfo[] = | |
{ | |
{ LXsPKG_SUPERTYPE, LXsITYPE_TOOLOP }, | |
{ LXsPKG_TOOL_TASK, LXs_TASK_ACTR }, | |
{ LXsPKG_TOOL_ORDER, LXs_ORD_ACTR }, | |
{ LXsPKG_TOOL_CHANNEL, LXsICHAN_TOOL_OBJ }, | |
{ 0 } | |
}; | |
enum ePacketOffset | |
{ | |
ePacketOffset_Subject2, | |
ePacketOffset_MAX | |
}; | |
class ToolOperation : | |
public CLxImpl_ToolOperation | |
{ | |
public: | |
static void | |
initialize() | |
{ | |
CLxGenericPolymorph *srv = new CLxPolymorph<ToolOperation>; | |
srv->AddInterface(new CLxIfc_ToolOperation<ToolOperation>); | |
lx::AddSpawner(sToolOpName, srv); | |
} | |
static ToolOperation* | |
Spawn( | |
void **ppvObj) | |
{ | |
static CLxSpawner<ToolOperation> spawner(sToolOpName); | |
return spawner.Alloc(ppvObj); | |
} | |
ToolOperation() | |
{ | |
for(unsigned int i = 0; i < ePacketOffset_MAX; i++) | |
{ | |
mPacketOffsets[i] = 0; | |
} | |
} | |
LXxO_ToolOperation_Evaluate // LxResult (ILxUnknownID vts) | |
{ | |
CLxUser_VectorStack vector(vts); | |
if(true == vector.test()) | |
{ | |
CLxUser_Subject2Packet subjectPacket; | |
if(true == vector.ReadObject(mPacketOffsets[ePacketOffset_Subject2], subjectPacket)) | |
{ | |
CLxUser_LayerScan layerScan; | |
if(true == subjectPacket.BeginScan(LXf_LAYERSCAN_EDIT, layerScan)) | |
{ | |
unsigned int count = layerScan.NumLayers(); | |
for(unsigned int i = 0; i < count; i++) | |
{ | |
CLxUser_Mesh mesh; | |
if(true == layerScan.EditMeshByIndex(i, mesh)) | |
createPlane(mesh, mSize); | |
} | |
return LXe_OK; | |
} | |
} | |
} | |
return LXe_FAILED; | |
} | |
void | |
createPlane( | |
CLxUser_Mesh &mesh, | |
double size) | |
{ | |
if(false == mesh.test() || lx::Compare(size, 0.0) == LXi_EQUAL_TO) | |
return; | |
static double positions[4][3] = {{-1.0, 0.0, -1.0}, | |
{ 1.0, 0.0, -1.0}, | |
{ 1.0, 0.0, 1.0}, | |
{-1.0, 0.0, 1.0}}; | |
CLxUser_Point point(mesh); | |
LXtPointID pointIDs[4]; | |
for(unsigned int i = 0; i < 4; i++) | |
{ | |
LXtVector temp; | |
LXx_VSCL3(temp, positions[i], mSize); | |
point.New(temp, &pointIDs[i]); | |
} | |
CLxUser_Polygon polygon(mesh); | |
LXtPolygonID polygonID = NULL; | |
polygon.New(LXiPTYP_FACE, pointIDs, 4, 1, &polygonID); | |
mesh.SetMeshEdits(LXf_MESHEDIT_GEOMETRY); | |
} | |
void | |
setSize( | |
double size) | |
{ | |
mSize = std::fabs(size); | |
} | |
bool | |
setPacketOffset( | |
unsigned int index, | |
unsigned int offset) | |
{ | |
if(index >= ePacketOffset_MAX) | |
return false; | |
mPacketOffsets[index] = offset; | |
return true; | |
} | |
private: | |
unsigned int mPacketOffsets[ePacketOffset_MAX]; | |
double mSize; | |
}; | |
class Tool : | |
public CLxImpl_Tool, | |
public CLxImpl_ToolModel, | |
public CLxDynamicAttributes | |
{ | |
public: | |
static void | |
initialize () | |
{ | |
CLxGenericPolymorph *srv = new CLxPolymorph<Tool>; | |
srv->AddInterface(new CLxIfc_Tool<Tool>); | |
srv->AddInterface(new CLxIfc_ToolModel<Tool>); | |
srv->AddInterface(new CLxIfc_Attributes<Tool>); | |
srv->AddInterface(new CLxIfc_AttributesUI<Tool>); | |
srv->AddInterface(new CLxIfc_StaticDesc<Tool>); | |
lx::AddSpawner(sToolName, srv); | |
} | |
static Tool* | |
Spawn( | |
void **ppvObj) | |
{ | |
static CLxSpawner<Tool> spawner(sToolName); | |
return spawner.Alloc(ppvObj); | |
} | |
Tool() | |
{ | |
dyna_Add(sAttrSize, LXsTYPE_DISTANCE); | |
attr_SetFlt(0, 0.5); | |
for(unsigned int i = 0; i < ePacketOffset_MAX; i++) | |
{ | |
mPacketOffsets[i] = 0; | |
} | |
CLxUser_PacketService pktSvc; | |
if(true == pktSvc.NewVectorType(LXsCATEGORY_TOOL, mVecType)) | |
{ | |
if(LXx_OK(pktSvc.AddPacket(mVecType, LXsP_TOOL_SUBJECT2, LXfVT_GET))) | |
mPacketOffsets[ePacketOffset_Subject2] = pktSvc.GetOffset(LXsCATEGORY_TOOL, LXsP_TOOL_SUBJECT2); | |
} | |
} | |
LXxO_Tool_VectorType // LXtObjectID (void) | |
{ | |
return mVecType.m_loc; | |
} | |
LXxO_Tool_Order // const char * (void) | |
{ | |
return LXs_ORD_ACTR; | |
} | |
LXxO_Tool_Task // LXtID4 (void) | |
{ | |
return LXi_TASK_ACTR; | |
} | |
LXxO_Tool_GetOp // LxResult (void **ppvObj, unsigned flags) | |
{ | |
*ppvObj = NULL; | |
ToolOperation *toolOp = ToolOperation::Spawn(ppvObj); | |
if(NULL != toolOp) | |
{ | |
toolOp->setSize(dyna_Float(0, 0.5)); | |
for(unsigned int i = 0; i < ePacketOffset_MAX; i++) | |
{ | |
toolOp->setPacketOffset(i, mPacketOffsets[i]); | |
} | |
} | |
return ((NULL != *ppvObj) ? LXe_OK : LXe_FAILED); | |
} | |
static LXtTagInfoDesc descInfo[]; | |
private: | |
CLxUser_VectorType mVecType; | |
unsigned int mPacketOffsets[ePacketOffset_MAX]; | |
}; | |
LXtTagInfoDesc Tool::descInfo[] = | |
{ | |
{ LXsTOOL_USETOOLOP, "." }, | |
{ 0 } | |
}; | |
class ModifierElement : | |
public CLxItemModifierElement | |
{ | |
public: | |
ModifierElement( | |
CLxUser_Evaluation &eval, | |
ILxUnknownID item) | |
{ | |
mSizeChannel = -1; | |
mToolChannel = -1; | |
CLxUser_Item modifierItem(item); | |
if(true == eval.test() && true == modifierItem.test()) | |
{ | |
mSizeChannel = eval.AddChan(item, sAttrSize, LXfECHAN_READ); | |
mToolChannel = eval.AddChan(item, LXsICHAN_TOOL_OBJ, LXfECHAN_WRITE); | |
} | |
} | |
void | |
Eval( | |
CLxUser_Evaluation &eval, | |
CLxUser_Attributes &attr) LXx_OVERRIDE | |
{ | |
if(false == eval.test() || false == attr.test() || mSizeChannel < 0 || mToolChannel < 0) | |
return; | |
ILxUnknownID object = NULL; | |
Tool *tool = Tool::Spawn((void**)&object); | |
if(NULL != tool) | |
{ | |
CLxUser_ValueReference valueReference; | |
if (true == attr.ObjectRW ((unsigned int) mToolChannel, valueReference)) | |
{ | |
valueReference.SetObject(object); | |
CLxUser_Attributes toolAttr(object); | |
if(true == toolAttr.test()) | |
toolAttr.Set(0, attr.Float((unsigned int) mSizeChannel)); | |
} | |
lx::UnkRelease(object); | |
} | |
} | |
private: | |
int mSizeChannel, mToolChannel; | |
}; | |
class ModifierServer : | |
public CLxItemModifierServer | |
{ | |
public: | |
static void | |
initialize() | |
{ | |
CLxGenericPolymorph *srv = new CLxPolymorph<ModifierServer>; | |
srv->AddInterface(new CLxIfc_EvalModifier<ModifierServer>); | |
srv->AddInterface(new CLxIfc_TagDescription<ModifierServer>); | |
lx::AddServer(sModifierName, srv); | |
} | |
const char* | |
ItemType() LXx_OVERRIDE | |
{ | |
return sPackageName; | |
} | |
CLxItemModifierElement* | |
Alloc( | |
CLxUser_Evaluation &eval, | |
ILxUnknownID item) LXx_OVERRIDE | |
{ | |
return new ModifierElement(eval, item); | |
} | |
}; | |
void | |
initialize() | |
{ | |
Package::initialize(); | |
ToolOperation::initialize(); | |
Tool::initialize(); | |
ModifierServer::initialize(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment