/******************************************************************************\*	Argus Numerical Environments - Plug In Extension, Release 1.0* *	Copyright © 1997 Argus Holdings Ltd.  All rights reserved.** THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF Argus Holdings Ltd..* The copyright notice above does not evidence any* actual or intended publication of such source code********************************************************************************** * This project was contributed by Argus Development Group, * to support virtual nodes**  MODULE:      VirtualNodesPIE.C**  PURPOSE:     To provide a virtual nodes PIE. **  First Version: Jan 1997 by Shahar Dolev.**  COMMENTS:   *\******************************************************************************/#include "VirtualNodesPIE.hh"#include "ANECB.h"#define ASSERT(x)//==============================================================================// PIE Function definition//==============================================================================const long kNumNeighbours = 5;						// max number of neighbours for one elementconst long kEmpty = 0;									// marker for empty edgeRecordstruct edgeRecord {										// record for each edge								long neighbour;								long edge;							};struct elemRecord {										// record for each element								long number;								edgeRecord edges[kNumNeighbours];							};static elemRecord* sArray = 0;static long sArraySize = 0;static long sLastArrayEntry = -1;static long sLastElemAccessed = -1;//------------------------------------------------------------------------------// GInitMMFun://------------------------------------------------------------------------------// Function definition:// 	Define a MeshMaker function "VN_Init(N)"//// Parameters://	N - number of elements//// call this function to reset the array for N elements//------------------------------------------------------------------------------static voidGInitMMFun(const ANE_DOUBLE&	refPtX,				const ANE_DOUBLE&		refPtY,				ANE_INT16					numParams,				const ANE_PTR*			parameters,				ANE_PTR						myHandle,				ANE_PTR						reply ){	ANE_INT32 len = *(ANE_INT32*)(parameters[0]);	if (sArray)																		// if sArray was assigned		delete[] sArray;															// delete it	sArray = new elemRecord[len+1];										// declare 'len+1' element records	sArraySize = len+1;															// save array size		for (long i=0; i<sArraySize; i++)										// mark each edge as empty		for (long j=0; j<kNumNeighbours; j++)			sArray[i].edges[j].neighbour = kEmpty;	sLastArrayEntry = -1;														// init indices	sLastElemAccessed = -1;	*(ANE_DOUBLE*)reply = 0;} ////------------------------------------------------------------------------------// GSetNodeNumMMFun://------------------------------------------------------------------------------// Function definition:// 	Define a MeshMaker function "VN_SetNodeNum(Elem, Neighbour, Node)"//// Parameters://	Elem			- number of elements//	Neighbour	- number of neighbour elements//	Node			- virtual node number//// call this function to add a virtual node number N to element E// will return FALSE if problem encountered//------------------------------------------------------------------------------static voidGSetNodeNumMMFun(const ANE_DOUBLE&	refPtX,								const ANE_DOUBLE&	refPtY,								ANE_INT16				numParams,								const ANE_PTR*		parameters,								ANE_PTR					myHandle,								ANE_PTR					reply ){	ANE_INT32 elem = *(ANE_INT32*)(parameters[0]);	ANE_INT32 neighbour = *(ANE_INT32*)(parameters[1]);	ANE_INT32 node = *(ANE_INT32*)(parameters[2]);	ASSERT(sArray);	ASSERT(sLastArrayEntry < sArraySize);	if (elem != sLastElemAccessed)													// if 'elem' is different from the last elem accessed,	{																								// use the next array entry		sLastElemAccessed = elem;		sLastArrayEntry++;		sArray[sLastArrayEntry].number = elem;								// set element's record elem-number	}	long pos = sLastArrayEntry;	int done = 0;		for (long i=0; i<kNumNeighbours && !done; i++)						// loop for edge recoreds	{		if (kEmpty == sArray[pos].edges[i].neighbour)						// look for empty pair		{			sArray[pos].edges[i].neighbour = neighbour;						// fill it properly			sArray[pos].edges[i].edge = node;			done = 1;		}	} // for i	*(ANE_INT32*)reply = done;} ////------------------------------------------------------------------------------// GGetNodeNumMMFun://------------------------------------------------------------------------------// Function definition:// 	Define a MeshMaker function "VN_GetNodeNum(Elem, Neighbour)"//// Parameters://	Elem			- number of elements//	Neighbour	- number of neighbour elements//// call this function to get the virtual node number for the node on the edge between// Elem and Neighbour//------------------------------------------------------------------------------static voidGGetNodeNumMMFun(const ANE_DOUBLE&	refPtX,								const ANE_DOUBLE&	refPtY,								ANE_INT16				numParams,								const ANE_PTR*		parameters,								ANE_PTR					myHandle,								ANE_PTR					reply ){	ANE_INT32 elem = *(ANE_INT32*)(parameters[0]);	ANE_INT32 neighbour = *(ANE_INT32*)(parameters[1]);	ANE_INT32 node = -1;	ASSERT(sArray);	if (elem>neighbour && neighbour>=0)													// make sure elem > neighbour	{		long temp = elem;																				// swap elem with neighbour		elem = neighbour;		neighbour = temp;	}	long low = 0;																							// prepare for binary search	long high = sLastArrayEntry;	long mid = (low+high)/2;	long n;	while ((n=sArray[mid].number) != elem && high>low)							// do binary search	{		if (n>elem)			high = mid-1;		else			low = mid+1;		mid = (low+high)/2;	}	if (sArray[mid].number == elem)															// make sure elem was found	{		long pos = mid;		int done = 0;		for (long i=0; i<kNumNeighbours && !done; i++)								// now, search for neighbour		{			if (neighbour == sArray[pos].edges[i].neighbour)			{				node = sArray[pos].edges[i].edge;												// neighbour was found, get edge number				done = 1;			}		} // for i	}	*(ANE_INT32*)reply = node;} ////=================================================================//	PIE handling functions and declerations//=================================================================struct ANEPIEDesc* gPIEDescroptors[30];									// list of PIE descriptors for all parts//// prepare Project descriptor for VN_Init FunctionPIEANEPIEDesc					vnInitDesc;																	// create PIE descriptorFunctionPIEDesc			vnInitFDesc;																	// create TemplatePIEDesc additional information recordchar*							pnInit[2] = {"Elements", 0};										// list of parameter names for the functionenum EPIENumberType	ptInit[2] = {kPIEInteger, (EPIENumberType)0};		// list of parameter types for the function//// prepare Project descriptor for VN_SetNodeNum FunctionPIEANEPIEDesc					vnSetNodeNumDesc;																	// create PIE descriptorFunctionPIEDesc			vnSetNodeNumFDesc;																// create TemplatePIEDesc additional information recordchar*							pnSetNodeNum[4] = {"Element", "Neighbour", "Node", 0};							// list of parameter names for the functionenum EPIENumberType	ptSetNodeNum[4] = {kPIEInteger, kPIEInteger, kPIEInteger, (EPIENumberType)0};	// list of parameter types for the function//// prepare Project descriptor for VN_GetNodeNum FunctionPIEANEPIEDesc					vnGetNodeNumDesc;																	// create PIE descriptorFunctionPIEDesc			vnGetNodeNumFDesc;																// create TemplatePIEDesc additional information recordchar*							pnGetNodeNum[3] = {"Element", "Neighbour", 0};										// list of parameter names for the functionenum EPIENumberType	ptGetNodeNum[3] = {kPIEInteger, kPIEInteger, (EPIENumberType)0};		// list of parameter types for the function#pragma export onvoidGetANEFunctions(ANE_INT32& numNames, struct ANEPIEDesc**& descriptors){ 	numNames = 0;																			// initialize the number of PIEs	//	// fill in the PIE descriptor	vnInitDesc.name				= "VN_Init";											// PIE name	vnInitDesc.type				= kFunctionPIE;													// type of PIE: FunctionPIE	vnInitDesc.descriptor		= &vnInitFDesc;											// address of additional information record	//	// fill in the FunctionPIEDesc additional information record	vnInitFDesc.version					= FUNCTION_PIE_VERSION;							// descriptor version, use constant here...	vnInitFDesc.name						= "VN_Init";										// name of function	vnInitFDesc.functionFlags			= kFunctionIsHidden;															// flags for function	vnInitFDesc.address					= GInitMMFun;										// the address of the function	vnInitFDesc.returnType				= kPIEInteger;													// the function returns float	vnInitFDesc.numParams				= 1;																// the function takes 1 mandatory parameter	vnInitFDesc.numOptParams		= 0;																// the function takes 0 optional parameters	vnInitFDesc.paramNames			= pnInit;												// the array of parameter names	vnInitFDesc.paramTypes			= ptInit;												// the array of parameter types	vnInitFDesc.functionHandle			= 0;																// a pointer to function's private information (not used here)	vnInitFDesc.category					= "";																// function category (not used here)	gPIEDescroptors[numNames++] = &vnInitDesc;												// put descriptor into array	//	// fill in the PIE descriptor	vnSetNodeNumDesc.name				= "VN_SetNodeNum";											// PIE name	vnSetNodeNumDesc.type				= kFunctionPIE;													// type of PIE: FunctionPIE	vnSetNodeNumDesc.descriptor		= &vnSetNodeNumFDesc;											// address of additional information record	//	// fill in the FunctionPIEDesc additional information record	vnSetNodeNumFDesc.version					= FUNCTION_PIE_VERSION;							// descriptor version, use constant here...	vnSetNodeNumFDesc.name						= "VN_SetNodeNum";										// name of function	vnSetNodeNumFDesc.functionFlags			= kFunctionIsHidden;															// flags for function	vnSetNodeNumFDesc.address					= GSetNodeNumMMFun;										// the address of the function	vnSetNodeNumFDesc.returnType				= kPIEInteger;													// the function returns float	vnSetNodeNumFDesc.numParams				= 3;																// the function takes 2 mandatory parameter	vnSetNodeNumFDesc.numOptParams		= 0;																// the function takes 0 optional parameters	vnSetNodeNumFDesc.paramNames			= pnSetNodeNum;												// the array of parameter names	vnSetNodeNumFDesc.paramTypes			= ptSetNodeNum;												// the array of parameter types	vnSetNodeNumFDesc.functionHandle			= 0;																// a pointer to function's private information (not used here)	vnSetNodeNumFDesc.category					= "";																// function category (not used here)	gPIEDescroptors[numNames++] = &vnSetNodeNumDesc;												// put descriptor into array	//	// fill in the PIE descriptor	vnGetNodeNumDesc.name				= "VN_GetNodeNum";											// PIE name	vnGetNodeNumDesc.type				= kFunctionPIE;													// type of PIE: FunctionPIE	vnGetNodeNumDesc.descriptor		= &vnGetNodeNumFDesc;											// address of additional information record	//	// fill in the FunctionPIEDesc additional information record	vnGetNodeNumFDesc.version					= FUNCTION_PIE_VERSION;							// descriptor version, use constant here...	vnGetNodeNumFDesc.name						= "VN_GetNodeNum";										// name of function	vnGetNodeNumFDesc.functionFlags			= kFunctionIsHidden;															// flags for function	vnGetNodeNumFDesc.address					= GGetNodeNumMMFun;										// the address of the function	vnGetNodeNumFDesc.returnType				= kPIEInteger;													// the function returns float	vnGetNodeNumFDesc.numParams				= 2;																// the function takes 1 mandatory parameter	vnGetNodeNumFDesc.numOptParams		= 0;																// the function takes 0 optional parameters	vnGetNodeNumFDesc.paramNames			= pnGetNodeNum;												// the array of parameter names	vnGetNodeNumFDesc.paramTypes			= ptGetNodeNum;												// the array of parameter types	vnGetNodeNumFDesc.functionHandle			= 0;																// a pointer to function's private information (not used here)	vnGetNodeNumFDesc.category					= "";																// function category (not used here)	gPIEDescroptors[numNames++] = &vnGetNodeNumDesc;												// put descriptor into array	descriptors = gPIEDescroptors;} 
