infinite GeUserArea Rectangle inside GeDialogue
-
On 10/01/2015 at 11:30, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 13+
Platform: Windows ;
Language(s) : C++ ;---------
I have a GeDialogue, it contains a GeUserArea , what I want is to create a typically infinite area similar to xpresso.I thought about drawing the background with DrawRectangle() using quite large numbers, but is this the correct approach? or I'm doing it wrong!!
another question: can I draw a user area inside another user area?? "like nodes, a node can be a group which contains another nodes"
and what about ScrollArea()? I tried using it, but it gives me errors in debug console "DrawBegin/End ist faul B" and hangs Cinema 4D
-
On 10/01/2015 at 12:23, xxxxxxxx wrote:
The GeUserArea must be a finite size. The 'infinite' part is in using a virtual window into your display space that is represented by the GeUserArea to draw into. Store your virtual space window offsets (x, y) and draw accordingly with GeUserArea::Draw().
You can't add a GeUserArea to a GeUserArea. I draw nodes into it as separate entities. So, I have a routine that knows how to draw a node and another that knows how to draw connections between nodes and so on. With the bounding coordinates known, you can clip out nodes that aren't in the view and use SetClippingRegion() for anything partially drawn.
For an infinite virtual space window set up, I would not use ScrollArea(). Handle mouse grabs (like in Google Maps or something), update your window x,y (typically upper left) by the mouseX, mouseY deltas, redraw.
-
On 10/01/2015 at 20:14, xxxxxxxx wrote:
I see !
Tongue
[URL-REMOVED] , thanks a lot Robert.but here rises another 2 questions that are related:
1- if I use quite large GeUserArea Rectangle "for example (-10000000,-10000000. 10000000. 10000000) " is this possible? (this will be the world, and the window will be a tiny drawing region of 1000 x 1000 size)2- I want to do the behavior of re scaling , when you have an xpresso node, and mouse hovers the borders, it changes cursor and you can drag it to scale the node, how to do something similar? "in other words which functions to check, so if there is something automatic like a border function for them, or I will have to store all drawings """ nodes """ borders and check for mouse position against them "" will be a bad approach "" "
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
-
On 11/01/2015 at 04:15, xxxxxxxx wrote:
1. The GeUserArea rectangle is your window. Your world is virtual and the GUA rectangle shows the portion given by your window offsets and GUA dimensions. Typically, you would initialize this so that your world (0,0) are at the top, left of the GUA rectangle.
2. When did you think you wouldn't have to store the position and dimensions of every existing node in the virtual world (in the node, of course)? And then search them. This is exactly what I did in the development phase. There are many ways to increase search speed such as using sorting, hash tables, or binary space partitioning (divide and conquer).
// iSUserArea.IsOverNode //*---------------------------------------------------------------------------* ShaderNode* iSUserArea::IsOverNode(LONG* pX, LONG* pY, const LONG& mx, const LONG& my) //*---------------------------------------------------------------------------* { LONG h; // Is mouse over ShaderNode? (Z-order search) for (ShaderNode* snode = controller->GetLastSNode(); snode; snode = (ShaderNode* )snode->GetPrev()) { h = GetSNodeHeight(snode->GetType(), snode->GetExpanded(), snode->GetShowPreview()); snode->GetPos(pX, pY); (*pX) -= windowX; (*pY) -= windowY; if ((mx >= *pX) && (mx < (*pX+cellWidth)) && (my >= *pY) && (my < (*pY+h))) return snode; } return NULL; }
After you determine if you are over a node and which one, then you can refine where in the node to define locational functionality.
*Note: my nodes here are all a fixed width with varying height by node type.
-
On 11/01/2015 at 05:05, xxxxxxxx wrote:
thanks Robert , I know that I have to store all node data in the node class "like node size, position, inputs and outputs connections, etc.." , one last question that I didn't find an answer in the documentation:
DrawMsg(Int32 x1, Int32 y1, Int32 x2, Int32 y2, const BaseContainer& msg);
what are the values of x1,y1, x2,y2? is the the "window" of the world?
-
On 11/01/2015 at 05:34, xxxxxxxx wrote:
I wouldn't worry about them. I use them to set clipping and clear before drawing and that is it:
// GeUserArea.Draw //*---------------------------------------------------------------------------* void iSUserArea::DrawMsg(LONG x1, LONG y1, LONG x2, LONG y2, const BaseContainer& msg) //*---------------------------------------------------------------------------* { // No flicker OffScreenOn(); SetClippingRegion(x1,y1,x2,y2); // Clear area DrawSetPen(isUAColor[ISCOLOR_BG]); DrawRectangle(x1,y1,x2,y2); ...
What is more important is that you maintain your window offset in your GUA-derived class. As noted, I initialize my windowX and windowY to (0,0) and then update them with LMB-down scrolls (I'm doing rectangular selection at the end, but it is easily modified for scrolling behavior) :
// iSUserArea.GetWindowOffset //*---------------------------------------------------------------------------* void iSUserArea::GetWindowOffset(LONG* wx, LONG* wy) //*---------------------------------------------------------------------------* { *wx = windowX; *wy = windowY; } // iSUserArea.OffsetWindow //*---------------------------------------------------------------------------* void iSUserArea::OffsetWindow(const LONG& dx, const LONG& dy) //*---------------------------------------------------------------------------* { windowX += dx; windowY += dy; Redraw(); } // GeUserArea.InputEvent() //*---------------------------------------------------------------------------* Bool iSUserArea::InputEvent(const BaseContainer &msg) //*---------------------------------------------------------------------------* { // Mouse Events if (msg.GetLong(BFM_INPUT_DEVICE) == BFM_INPUT_MOUSE) return HandleMouseEvents(msg); return FALSE; } // iSUserArea.HandleMouse //*---------------------------------------------------------------------------* Bool iSUserArea::HandleMouseEvents(const BaseContainer& msg) //*---------------------------------------------------------------------------* { // Get Mouse Click location and other information LONG chn = msg.GetLong(BFM_INPUT_CHANNEL); // Left Button if (chn == BFM_INPUT_MOUSELEFT) return HandleMouse_LeftButton(msg); // Right Button: Context PopupMenu if (chn == BFM_INPUT_MOUSERIGHT) return HandleMouse_RightButton(msg.GetLong(BFM_INPUT_X), msg.GetLong(BFM_INPUT_Y)); return TRUE; } //*---------------------------------------------------------------------------* Bool iSUserArea::HandleMouse_LeftButton(const BaseContainer& msg) //*---------------------------------------------------------------------------* { // Get Mouse Click location and other information LONG mx = msg.GetLong(BFM_INPUT_X); LONG my = msg.GetLong(BFM_INPUT_Y); Global2Local(&mx,&my); LONG pX, pY; ShaderNode* snode = IsOverNode(&pX, &pY, mx, my); // Do Something with ShaderNode if (snode) return HandleMouse_LBNode(snode, msg, pX, pY, mx, my); // Over Background Area // - Click - Remove all current selections // - Drag - Create/Add to/Remove from Selection return HandleMouse_LBBackground(msg, mx, my); } //*---------------------------------------------------------------------------* Bool iSUserArea::HandleMouse_LBBackground(const BaseContainer& msg, LONG mx, LONG my) //*---------------------------------------------------------------------------* { // Do nothing on DoubleClick if (msg.GetBool(BFM_INPUT_DOUBLECLICK)) { PUM_Edit(NULL); return TRUE; } // Check for Keyboard Qualifiers Bool selmode; LONG qua = msg.GetLong(BFM_INPUT_QUALIFIER); if (qua == QSHIFT) selmode = TRUE; else if (qua == QCTRL) selmode = FALSE; else { controller->SelectAll(FALSE); dialog->SelectedSNodes(FALSE); selmode = TRUE; } // Setup for dragging BaseContainer action(BFM_ACTION); BaseContainer state; action.SetLong(BFM_ACTION_ID,GetId()); action.SetLong(BFM_ACTION_VALUE,0L); // General variables LONG width = GetWidth(); LONG height = GetHeight(); LONG hw = width>>1; LONG hh = height>>1; LONG rectX1 = mx; LONG rectY1 = my; LONG rectX2, rectY2; // Drag Selecting startX = rectX1; startY = rectY1; drawMode = ISUA_DRAWMODE_SELECTING; while (GetInputState(BFM_INPUT_MOUSE,BFM_INPUT_MOUSELEFT,state)) { if (state.GetLong(BFM_INPUT_VALUE) == 0) break; endX = state.GetLong(BFM_INPUT_X); endY = state.GetLong(BFM_INPUT_Y); Global2Local(&endX,&endY); mx = endX/2L; my = endY/2L; // Check for UserArea boundary, scroll if necessary if (endX <= 0L) { windowX += mx; startX -= mx; } else if (endX >= width) { windowX += (mx-hw); startX -= (mx-hw); } if (endY <= 0L) { windowY += my; startY -= my; } else if (endY >= height) { windowY += (my-hh); startY -= (my-hh); } Redraw(); action.SetLong(BFM_ACTION_INDRAG,TRUE); SendParentMessage(action); } drawMode = ISUA_DRAWMODE_NORMAL; rectX2 = endX; rectY2 = endY; // Swap so that 1 is always UL, 2 LR if (rectX1 > rectX2) { mx = rectX1; rectX1 = rectX2; rectX2 = mx; } if (rectY1 > rectY2) { my = rectY1; rectY1 = rectY2; rectY2 = my; } // Find and Select/Deselect all ShaderNodes overlapped by Rectangle LONG pX, pY; for (ShaderNode* snode = controller->GetFirstSNode(); snode; snode = (ShaderNode* )snode->GetNext()) { snode->GetPos(&pX, &pY); pX -= windowX; mx = pX+cellWidth; pY -= windowY; my = pY+GetSNodeHeight(snode->GetType(), snode->GetExpanded(), snode->GetShowPreview()); if ((my < rectY1) || (pY > rectY2) || (mx < rectX1) || (pX > rectX2)) continue; controller->SelectNode(snode, selmode); if (!selmode) dialog->SelectedSNodes(controller->AreSelectedSNodes()); else dialog->SelectedSNodes(TRUE); } // Update and Notify Redraw(); action.SetLong(BFM_ACTION_INDRAG,FALSE); SendParentMessage(action); return TRUE; }
-
On 11/01/2015 at 06:48, xxxxxxxx wrote:
thanks a lot Robert
-
On 11/01/2015 at 07:36, xxxxxxxx wrote:
Can I ask you guys a stupid question?
What are these "Nodes" in your code. And where do the come from?I've used the UA to draw shapes and move them around.
But how to you create these "nodes" that you can connect together in the UA?I'm not having any luck with trying to put an xpresso window in a GeDialog. I can only launch a new one.
So I'm thinking that maybe I need to do what you guys are doing to creating my own "nodes" in my own UA. Instead of trying to use the existing xpresso window?
But I don't know how to create these "Nodes".Sorry for the newbish question.
-ScottA -
On 11/01/2015 at 09:13, xxxxxxxx wrote:
Scott, indeed, these nodes are classes I wrote. The base class establishes a doubly-linked list set up (for easy insertion/deletion of nodes), position and size of the node graphically, inputs and outputs as NodeInput classes for connectivity, node ids, flags, methods, and other information. The code is rather old and I would probably do it differently today having learned much over time.
//////////////////////////////////////////////////////////////// // NodeInput.h //////////////////////////////////////////////////////////////// // Node Input Class include //////////////////////////////////////////////////////////////// #ifndef _NODEINPUT_H_ #define _NODEINPUT_H_ #include "ShaderNodeDefs.h" // Predefine for cross-referencing class ShaderNode; // Input within Node class NodeInput { private: // NodeInput name String name; // Vector(x,y,z), Color(R,G,B), Value(current,min,max), List(current,listtype,numitems) Vector value; // Value Type - see NodeInput Type Defintions in ShaderNodeDefs LONG type; // Whether Node accepts input connections Bool acceptConnection; // ShaderNodes connected to this NodeInput LONG numNodes; ShaderNode* node; // - id of ShaderNode (for Read/Write/CopyTo) LONG id; // ID of corresponding Edit Gadget in Dialog LONG editID; // Name of bitmap file String file; public: NodeInput(); ~NodeInput(); // Initialize NodeInput void Init(const String& t_name, const Vector& t_value, const LONG& t_type, const Bool& t_acceptConnection, ShaderNode* t_node, const String& t_file); // String name void SetName(const String& t_name); String GetName(); // Vector value void SetValue(const Vector& t_value); void SetValueBool(const Bool& t_value); void SetValueList(const LONG& t_value); void SetValueReal(const Real& t_value); Vector GetValue(); Bool GetValueBool(); LONG GetValueList(); Real GetValueReal(); // LONG type Bool IsInstanceOf(const LONG& t_type); void SetType(const LONG& t_type); LONG GetType(); // Bool acceptConnection void SetAcceptConnection(const Bool& t_acceptConnection); Bool GetAcceptConnection(); // ShaderNode *node void SetNode(ShaderNode* t_node); ShaderNode* GetNode(); void SetNodeID(const LONG& t_id); LONG GetNodeID(); // String file void SetFile(String t_file); String GetFile(); // LONG editID void SetEditID(const LONG& t_editID); LONG GetEditID(); // Read/Write/CopyTo Bool Read(HyperFile* hf, LONG level); Bool Write(HyperFile* hf); Bool CopyTo(NodeInput* dni, Bool dataOnly); }; #endif //_NODEINPUT_H_
//////////////////////////////////////////////////////////////// // NodeInput.cpp //////////////////////////////////////////////////////////////// // Node Input Class //////////////////////////////////////////////////////////////// // Includes #include "../glload.h" #include "../general.h" #include "NodeInput.h" #include "ShaderNode.h" // **************************************************************************** // METHODS: NodeInput // Constructor #1 //*---------------------------------------------------------------------------* NodeInput::NodeInput() //*---------------------------------------------------------------------------* { name = String(""); value = Vector(0.0); type = NODEINPUTTYPE_NONE; acceptConnection = FALSE; numNodes = 0L; node = NULL; id = -1L; file = String(""); editID = -1L; } // Destructor //*---------------------------------------------------------------------------* NodeInput::~NodeInput() //*---------------------------------------------------------------------------* { } // Initialize NodeInput //*---------------------------------------------------------------------------* void NodeInput::Init(const String& t_name, const Vector& t_value, const LONG& t_type, const Bool& t_acceptConnection, ShaderNode* t_node, const String& t_file) //*---------------------------------------------------------------------------* { name = t_name; value = Vector(t_value.x, t_value.y, t_value.z); type = t_type; acceptConnection = t_acceptConnection; node = t_node; if (node) id = node->GetID(); else id = -1L; file = t_file; } // String name //*---------------------------------------------------------------------------* void NodeInput::SetName(const String& t_name) //*---------------------------------------------------------------------------* { name = t_name; } //*---------------------------------------------------------------------------* String NodeInput::GetName() //*---------------------------------------------------------------------------* { return name; } // Vector value //*---------------------------------------------------------------------------* void NodeInput::SetValue(const Vector& t_value) //*---------------------------------------------------------------------------* { value = Vector(t_value.x, t_value.y, t_value.z); } //*---------------------------------------------------------------------------* void NodeInput::SetValueBool(const Bool& t_value) //*---------------------------------------------------------------------------* { value.x = (Real)t_value; } //*---------------------------------------------------------------------------* void NodeInput::SetValueList(const LONG& t_value) //*---------------------------------------------------------------------------* { value.x = (Real)t_value; } //*---------------------------------------------------------------------------* void NodeInput::SetValueReal(const Real& t_value) //*---------------------------------------------------------------------------* { value.x = t_value; } //*---------------------------------------------------------------------------* Vector NodeInput::GetValue() //*---------------------------------------------------------------------------* { return value; } //*---------------------------------------------------------------------------* Bool NodeInput::GetValueBool() //*---------------------------------------------------------------------------* { return (Bool)(value.x); } //*---------------------------------------------------------------------------* LONG NodeInput::GetValueList() //*---------------------------------------------------------------------------* { return (LONG)(value.x); } //*---------------------------------------------------------------------------* Real NodeInput::GetValueReal() //*---------------------------------------------------------------------------* { return value.x; } // Bool acceptConnection //*---------------------------------------------------------------------------* void NodeInput::SetAcceptConnection(const Bool& t_acceptConnection) //*---------------------------------------------------------------------------* { acceptConnection = t_acceptConnection; } //*---------------------------------------------------------------------------* Bool NodeInput::GetAcceptConnection() //*---------------------------------------------------------------------------* { return acceptConnection; } // LONG type //*---------------------------------------------------------------------------* Bool NodeInput::IsInstanceOf(const LONG& t_type) //*---------------------------------------------------------------------------* { return (type == t_type); } //*---------------------------------------------------------------------------* void NodeInput::SetType(const LONG& t_type) //*---------------------------------------------------------------------------* { type = t_type; } //*---------------------------------------------------------------------------* LONG NodeInput::GetType() //*---------------------------------------------------------------------------* { return type; } // ShaderNode* node //*---------------------------------------------------------------------------* void NodeInput::SetNode(ShaderNode* t_node) //*---------------------------------------------------------------------------* { node = t_node; if (node) id = node->GetID(); else id = -1L; } //*---------------------------------------------------------------------------* ShaderNode* NodeInput::GetNode() //*---------------------------------------------------------------------------* { return node; } //*---------------------------------------------------------------------------* void NodeInput::SetNodeID(const LONG& t_id) //*---------------------------------------------------------------------------* { id = t_id; } //*---------------------------------------------------------------------------* LONG NodeInput::GetNodeID() //*---------------------------------------------------------------------------* { return id; } // String file //*---------------------------------------------------------------------------* void NodeInput::SetFile(String t_file) //*---------------------------------------------------------------------------* { file = t_file; } //*---------------------------------------------------------------------------* String NodeInput::GetFile() //*---------------------------------------------------------------------------* { return file; } // LONG editID //*---------------------------------------------------------------------------* void NodeInput::SetEditID(const LONG& t_editID) //*---------------------------------------------------------------------------* { editID = t_editID; } //*---------------------------------------------------------------------------* LONG NodeInput::GetEditID() //*---------------------------------------------------------------------------* { return editID; } // Read/Write/CopyTo // - Read NodeInput info //*---------------------------------------------------------------------------* Bool NodeInput::Read(HyperFile* hf, LONG level) //*---------------------------------------------------------------------------* { if (!hf->ReadString(&name)) return FALSE; if (!hf->ReadVector(&value)) return FALSE; if (!hf->ReadLong(&type)) return FALSE; if (!hf->ReadBool(&acceptConnection)) return FALSE; // ShaderNode* node - Unique Index! if (!hf->ReadLong(&id)) return FALSE; if (!hf->ReadString(&file)) return FALSE; return TRUE; } // - Write NodeInput info //*---------------------------------------------------------------------------* Bool NodeInput::Write(HyperFile* hf) //*---------------------------------------------------------------------------* { if (!hf->WriteString(name)) return FALSE; if (!hf->WriteVector(value)) return FALSE; if (!hf->WriteLong(type)) return FALSE; if (!hf->WriteBool(acceptConnection)) return FALSE; // ShaderNode* node - Unique Index! if (!hf->WriteLong(id)) return FALSE; if (!hf->WriteString(file)) return FALSE; return TRUE; } // - Copy Source NodeInput info to Destination NodeInput //*---------------------------------------------------------------------------* Bool NodeInput::CopyTo(NodeInput* dni, Bool dataOnly) //*---------------------------------------------------------------------------* { dni->name = name; dni->value = Vector(value.x, value.y, value.z); dni->type = type; dni->acceptConnection = acceptConnection; dni->file = file; if (!dataOnly) dni->id = id; return TRUE; }
//////////////////////////////////////////////////////////////// // ShaderNode.h //////////////////////////////////////////////////////////////// // Shader Node Base Class include //////////////////////////////////////////////////////////////// #ifndef _SHADERNODE_H_ #define _SHADERNODE_H_ #include "ShaderNodeDefs.h" // ShaderNode flags #define SHADERNODE_FLAGS_NONE 0L #define SHADERNODE_FLAGS_SHOWPREVIEW (1<<0) #define SHADERNODE_FLAGS_SELECTED (1<<1) #define SHADERNODE_FLAGS_CONNECTING (1<<2) #define SHADERNODE_FLAGS_EXPANDED (1<<3) //class glload; class NodeInput; struct NodeInputDef; // Node within Tree class ShaderNode { public: ShaderNode* prev; ShaderNode* next; // - ShaderNode name String name; // - UL Position within interface LONG xPos; LONG yPos; // - Unique ID LONG id; // - Flags (see above) LONG flags; // - Node Type - see ShaderNode Type Definitions in ShaderNodeDefs LONG type; // NodeInputs: count LONG numNodeInputs; LONG acceptCount; // Number of outgoing connections LONG connections; NodeInput* nodeInputs; // OpenGL Support //glload* previewGL; // Bitmaps BaseBitmap* previewBitmap; // For Output() ShaderNode* sn; NodeInput* ni; // Methods ShaderNode(); ShaderNode(const LONG& t_type, const LONG& t_numNodeInputs, const LONG& t_xPos, const LONG& t_yPos, const LONG& t_flags); virtual ~ShaderNode(); Bool Append(ShaderNode* previous); void Remove(); ShaderNode* GetPrev(); ShaderNode* GetNext(); // Initial ShaderNode Bool Init(const LONG& t_xPos, const LONG& t_yPos, const LONG& t_pDim, const LONG& t_flags); Bool InitInputs(NodeInputDef* nid); // String name void SetName(const String& t_name); String GetName(); // Vector pos void SetPos(const LONG& t_xPos, const LONG& t_yPos); void GetPos(LONG* t_xPos, LONG* t_yPos); void Move(const LONG& xDelta, const LONG& yDelta); // LONG id void SetID(const LONG& t_id); LONG GetID(); // Bool showPreview void SetShowPreview(const Bool& t_showPreview); Bool GetShowPreview(); void InvertShowPreview(); // Bool selected void SetSelected(const Bool& t_selected); Bool GetSelected(); // Bool expanded void SetExpanded(const Bool& t_expanded); Bool GetExpanded(); void InvertExpanded(); // LONG type Bool IsInstanceOf(const LONG& t_type); void SetType(const LONG& t_type); LONG GetType(); // NodeInputs LONG GetNodeCount(); LONG GetAcceptCount(); void ClearInputs(); // LONG connections void SetConnections(const LONG& count); void IncConnect(); void DecConnect(); LONG Connected(); // Bool connecting void SetConnecting(const Bool& t_connecting); Bool IsConnecting(); // NodeInput *nodeInputs - retrieve by index NodeInput* GetNodeInput(LONG index=0L); // Read/Write/CopyTo Bool Read(HyperFile* hf, LONG level); Bool Write(HyperFile* hf); Bool CopyTo(ShaderNode* dsn, Bool uniqueID); void ReestablishNodeLinks(ShaderNode* firstSNode); // Preview Bitmap BaseBitmap* GetPreview(); // Pure Virtuals (no more) void SetPreview(BaseMaterial* chn, Bool fromFile); Vector Output(BaseMaterial* chn, ChannelData* cd); }; #endif //_SHADERNODE_H_
//////////////////////////////////////////////////////////////// // ShaderNode.cpp //////////////////////////////////////////////////////////////// // Shader Node and Node Input Class //////////////////////////////////////////////////////////////// // Includes //#include "../glload.h" #include "../general.h" #include "NodeInputDefs.h" #include "NodeInput.h" #include "ShaderNode.h" #include "ShaderNodeStr.h" // **************************************************************************** // METHODS: ShaderNode // Constructor #1 //*---------------------------------------------------------------------------* ShaderNode::ShaderNode() //*---------------------------------------------------------------------------* { nodeInputs = NULL; previewBitmap = NULL; //previewGL = NULL; prev = NULL; next = NULL; xPos = 0L; yPos = 0L; flags = SHADERNODE_FLAGS_NONE; type = SHADERNODETYPE_NONE; numNodeInputs = 0L; acceptCount = 0L; connections = 0L; } // Constructor #2 //*---------------------------------------------------------------------------* ShaderNode::ShaderNode(const LONG& t_type, const LONG& t_numNodeInputs, const LONG& t_xPos, const LONG& t_yPos, const LONG& t_flags) //*---------------------------------------------------------------------------* { nodeInputs = NULL; previewBitmap = NULL; //previewGL = NULL; prev = NULL; next = NULL; xPos = t_xPos; yPos = t_yPos; flags = t_flags; type = t_type; numNodeInputs = t_numNodeInputs; acceptCount = 0L; connections = 0L; } // Destructor //*---------------------------------------------------------------------------* ShaderNode::~ShaderNode() //*---------------------------------------------------------------------------* { //gDelete(previewGL); BaseBitmap::Free(previewBitmap); bDelete(nodeInputs); } // Append node to list //*---------------------------------------------------------------------------* Bool ShaderNode::Append(ShaderNode* previous) //*---------------------------------------------------------------------------* { if (!previous) return ErrorException::Throw(GeLoadString(CANERR_MEMORY), "ShaderNode.Append.previous"); prev = previous; previous->next = this; return TRUE; } // Remove node from list //*---------------------------------------------------------------------------* void ShaderNode::Remove() //*---------------------------------------------------------------------------* { ShaderNode* p = prev; ShaderNode* n = next; prev = NULL; next = NULL; if (p) p->next = n; if (n) n->prev = p; } // Get Previous node //*---------------------------------------------------------------------------* ShaderNode* ShaderNode::GetPrev() //*---------------------------------------------------------------------------* { return prev; } // Get Next node //*---------------------------------------------------------------------------* ShaderNode* ShaderNode::GetNext() //*---------------------------------------------------------------------------* { return next; } // Initialize ShaderNode //*---------------------------------------------------------------------------* Bool ShaderNode::Init(const LONG& t_xPos, const LONG& t_yPos, const LONG& t_pDim, const LONG& t_flags) //*---------------------------------------------------------------------------* { if (!previewBitmap) { previewBitmap = BaseBitmap::Alloc(); if (!previewBitmap) return ErrorException::Throw(GeLoadString(CANERR_MEMORY), "ShaderNode.Init.previewBitmap"); if (previewBitmap->Init(t_pDim, t_pDim, 32L) != IMAGERESULT_OK) return ErrorException::Throw(GeLoadString(CANERR_MEMORY), "ShaderNode.Init.previewBitmap.Init"); previewBitmap->Clear(255L,255L,255L); } /* if (!previewGL) { previewGL = gNew glload; if (!previewGL) return ErrorException::Throw(GeLoadString(CANERR_MEMORY), "ShaderNode.Init.previewGL"); if (!previewGL->Init()) return ErrorException::Throw(GeLoadString(CANERR_GENERAL), "ShaderNode.Init.previewGL.Init"); } */ name = ShaderNodeStrings[type]; xPos = t_xPos; yPos = t_yPos; flags = t_flags; return TRUE; } // Initialize ShaderNode Inputs //*---------------------------------------------------------------------------* Bool ShaderNode::InitInputs(NodeInputDef* nid) //*---------------------------------------------------------------------------* { // Initialize NodeInputs by ShaderNode type // - Delete default NodeInput array bDelete(nodeInputs); nodeInputs = NULL; if (!numNodeInputs) return ErrorException::Throw(GeLoadString(CANERR_GENERAL), "ShaderNode.InitInputs.numNodeInputs"); // - Allocate NodeInput array nodeInputs = bNew NodeInput[numNodeInputs]; if (!nodeInputs) return ErrorException::Throw(GeLoadString(CANERR_MEMORY), "ShaderNode.InitInputs.nodeInputs"); // - Configure NodeInput array for (LONG i = 0L; i != numNodeInputs; ++i) { nodeInputs[i].Init(nid[i].name, Vector(nid[i].a, nid[i].b, nid[i].c), nid[i].type, nid[i].accept, NULL, String("")); if (nid[i].accept) ++acceptCount; } return TRUE; } // String name //*---------------------------------------------------------------------------* void ShaderNode::SetName(const String& t_name) //*---------------------------------------------------------------------------* { name = t_name; } //*---------------------------------------------------------------------------* String ShaderNode::GetName() //*---------------------------------------------------------------------------* { return name; } // LONG xPos, yPos //*---------------------------------------------------------------------------* void ShaderNode::SetPos(const LONG& t_xPos, const LONG& t_yPos) //*---------------------------------------------------------------------------* { xPos = t_xPos; yPos = t_yPos; } //*---------------------------------------------------------------------------* void ShaderNode::GetPos(LONG* t_xPos, LONG* t_yPos) //*---------------------------------------------------------------------------* { *t_xPos = xPos; *t_yPos = yPos; } //*---------------------------------------------------------------------------* void ShaderNode::Move(const LONG& xDelta, const LONG& yDelta) //*---------------------------------------------------------------------------* { // Move position by amount xPos += xDelta; yPos += yDelta; } // LONG id //*---------------------------------------------------------------------------* void ShaderNode::SetID(const LONG& t_id) //*---------------------------------------------------------------------------* { id = t_id; } //*---------------------------------------------------------------------------* LONG ShaderNode::GetID() //*---------------------------------------------------------------------------* { return id; } // Bool showPreview //*---------------------------------------------------------------------------* void ShaderNode::SetShowPreview(const Bool& t_showPreview) //*---------------------------------------------------------------------------* { if (t_showPreview) flags |= SHADERNODE_FLAGS_SHOWPREVIEW; else flags &= ~SHADERNODE_FLAGS_SHOWPREVIEW; } //*---------------------------------------------------------------------------* Bool ShaderNode::GetShowPreview() //*---------------------------------------------------------------------------* { return (flags & SHADERNODE_FLAGS_SHOWPREVIEW); } //*---------------------------------------------------------------------------* void ShaderNode::InvertShowPreview() //*---------------------------------------------------------------------------* { if (flags & SHADERNODE_FLAGS_SHOWPREVIEW) flags &= ~SHADERNODE_FLAGS_SHOWPREVIEW; else flags |= SHADERNODE_FLAGS_SHOWPREVIEW; } // Bool selected //*---------------------------------------------------------------------------* void ShaderNode::SetSelected(const Bool& t_selected) //*---------------------------------------------------------------------------* { if (t_selected) flags |= SHADERNODE_FLAGS_SELECTED; else flags &= ~SHADERNODE_FLAGS_SELECTED; } //*---------------------------------------------------------------------------* Bool ShaderNode::GetSelected() //*---------------------------------------------------------------------------* { return (flags & SHADERNODE_FLAGS_SELECTED); } // Bool expanded //*---------------------------------------------------------------------------* void ShaderNode::SetExpanded(const Bool& t_expanded) //*---------------------------------------------------------------------------* { if (t_expanded) flags |= SHADERNODE_FLAGS_EXPANDED; else flags &= ~SHADERNODE_FLAGS_EXPANDED; } //*---------------------------------------------------------------------------* Bool ShaderNode::GetExpanded() //*---------------------------------------------------------------------------* { return (flags & SHADERNODE_FLAGS_EXPANDED); } //*---------------------------------------------------------------------------* void ShaderNode::InvertExpanded() //*---------------------------------------------------------------------------* { if (flags & SHADERNODE_FLAGS_EXPANDED) flags &= ~SHADERNODE_FLAGS_EXPANDED; else flags |= SHADERNODE_FLAGS_EXPANDED; } // LONG type //*---------------------------------------------------------------------------* Bool ShaderNode::IsInstanceOf(const LONG& t_type) //*---------------------------------------------------------------------------* { return (type == t_type); } //*---------------------------------------------------------------------------* void ShaderNode::SetType(const LONG& t_type) //*---------------------------------------------------------------------------* { type = t_type; } //*---------------------------------------------------------------------------* LONG ShaderNode::GetType() //*---------------------------------------------------------------------------* { return type; } // LONG numNodeInputs //*---------------------------------------------------------------------------* LONG ShaderNode::GetNodeCount() //*---------------------------------------------------------------------------* { return numNodeInputs; } // LONG acceptCount //*---------------------------------------------------------------------------* LONG ShaderNode::GetAcceptCount() //*---------------------------------------------------------------------------* { return acceptCount; } //*---------------------------------------------------------------------------* void ShaderNode::ClearInputs() //*---------------------------------------------------------------------------* { if (!nodeInputs) return; for (LONG i = 0L; i != numNodeInputs; ++i) { nodeInputs[i].SetNode(NULL); } } // LONG connections //*---------------------------------------------------------------------------* void ShaderNode::SetConnections(const LONG& count) //*---------------------------------------------------------------------------* { connections = count; } //*---------------------------------------------------------------------------* void ShaderNode::IncConnect() //*---------------------------------------------------------------------------* { ++connections; } //*---------------------------------------------------------------------------* void ShaderNode::DecConnect() //*---------------------------------------------------------------------------* { if (connections > 0L) --connections; } //*---------------------------------------------------------------------------* LONG ShaderNode::Connected() //*---------------------------------------------------------------------------* { return connections; } // Bool connecting //*---------------------------------------------------------------------------* void ShaderNode::SetConnecting(const Bool& t_connecting) //*---------------------------------------------------------------------------* { if (t_connecting) flags |= SHADERNODE_FLAGS_CONNECTING; else flags &= ~SHADERNODE_FLAGS_CONNECTING; } //*---------------------------------------------------------------------------* Bool ShaderNode::IsConnecting() //*---------------------------------------------------------------------------* { return (flags & SHADERNODE_FLAGS_CONNECTING); } // NodeInput* nodeInputs - retrieve by index //*---------------------------------------------------------------------------* NodeInput* ShaderNode::GetNodeInput(LONG index) //*---------------------------------------------------------------------------* { if (!nodeInputs) return NULL; if (!numNodeInputs) return NULL; if (index >= numNodeInputs) return NULL; return &nodeInputs[index]; } // Read/Write/CopyTo // - Read NodeInput info //*---------------------------------------------------------------------------* Bool ShaderNode::Read(HyperFile* hf, LONG level) //*---------------------------------------------------------------------------* { if (!hf->ReadString(&name)) return FALSE; if (!hf->ReadLong(&xPos)) return FALSE; if (!hf->ReadLong(&yPos)) return FALSE; if (!hf->ReadLong(&id)) return FALSE; if (!hf->ReadLong(&flags)) return FALSE; if (!hf->ReadLong(&type)) return FALSE; if (!hf->ReadLong(&numNodeInputs)) return FALSE; if (!hf->ReadLong(&acceptCount)) return FALSE; if (!hf->ReadLong(&connections)) return FALSE; if (!nodeInputs) return TRUE; for (LONG i = 0L; i != numNodeInputs; ++i) { if (!nodeInputs[i].Read(hf, level)) return FALSE; } return TRUE; } // - Write NodeInput info //*---------------------------------------------------------------------------* Bool ShaderNode::Write(HyperFile* hf) //*---------------------------------------------------------------------------* { if (!hf->WriteString(name)) return FALSE; if (!hf->WriteLong(xPos)) return FALSE; if (!hf->WriteLong(yPos)) return FALSE; if (!hf->WriteLong(id)) return FALSE; if (!hf->WriteLong(flags)) return FALSE; if (!hf->WriteLong(type)) return FALSE; if (!hf->WriteLong(numNodeInputs)) return FALSE; if (!hf->WriteLong(acceptCount)) return FALSE; if (!hf->WriteLong(connections)) return FALSE; if (!nodeInputs) return TRUE; for (LONG i = 0L; i != numNodeInputs; ++i) { if (!nodeInputs[i].Write(hf)) return FALSE; } return TRUE; } // - Copy Source NodeInput info to Destination NodeInput //*---------------------------------------------------------------------------* Bool ShaderNode::CopyTo(ShaderNode* dsn, Bool uniqueID) //*---------------------------------------------------------------------------* { dsn->name = name; dsn->xPos = xPos; dsn->yPos = yPos; if (!uniqueID) dsn->id = id; dsn->flags = flags; dsn->type = type; dsn->numNodeInputs = numNodeInputs; dsn->acceptCount = acceptCount; dsn->connections = connections; if (!nodeInputs) return TRUE; for (LONG i = 0L; i != numNodeInputs; ++i) { nodeInputs[i].CopyTo(&(dsn->nodeInputs[i]), FALSE); } return TRUE; } // - Reestablish NodeInput* node links from id's //*---------------------------------------------------------------------------* void ShaderNode::ReestablishNodeLinks(ShaderNode* firstSNode) //*---------------------------------------------------------------------------* { if (!nodeInputs) return; ShaderNode* sn = NULL; for (LONG i = 0L; i != numNodeInputs; ++i) { ni = &nodeInputs[i]; for (sn = firstSNode; sn; sn = (ShaderNode* )sn->GetNext()) { if (sn->id == ni->GetNodeID()) { ni->SetNode(sn); break; } } } } //*---------------------------------------------------------------------------* void ShaderNode::SetPreview(BaseMaterial* chn, Bool fromFile) //*---------------------------------------------------------------------------* { } //*---------------------------------------------------------------------------* Vector ShaderNode::Output(BaseMaterial* chn, ChannelData* cd) //*---------------------------------------------------------------------------* { return Vector(1.0); } // BaseBitmap *previewBitmap //*---------------------------------------------------------------------------* BaseBitmap* ShaderNode::GetPreview() //*---------------------------------------------------------------------------* { /* if (!previewGL) return NULL; if (!previewBitmap) return NULL; // Create the shader node preview using OpenGL and store in 'previewBitmap' previewGL->Draw(); // pointers for processing UCHAR* redbuff = previewGL->GetRender(); UCHAR* greenbuff = redbuff+65536L; UCHAR* bluebuff = greenbuff+65536L; // 256x256 pixels LONG x; LONG r, g, b; for (LONG y = 255L; y != -1L; --y) { for (x = 0L; x != 256L; ++x) { r = *redbuff++; g = *greenbuff++; b = *bluebuff++; previewBitmap->SetPixel(x, y, r, g, b); } } */ return previewBitmap; }
-
On 11/01/2015 at 09:38, xxxxxxxx wrote:
Thanks a lot Robert.
I'll try to make sense of that. But it's lot of code to sift through.That's not your fault though. I know that link lists always requires a ton of code. Which is one reason why I was hoping I could use the existing xpresso node system and just add my own custom nodes to it. Instead of writing the entire thing by hand.
But I'm running into a lot of things I can't figure out.-ScottA