//(doit '(((500 250 3.1) (400 600 2.2)) (((500 200 1.1) (600 700 2.3) (800 600 3.3)) ((400 100 4.1) (500 700 2.6) (200 600 3.5)))))
[LispFunction("doit")]
public ResultBuffer Doit(ResultBuffer inBuf)
{
List<Point3d> _args = null;
List<List<Point3d>> _buf = null;
ResultBuffer outBuf = new ResultBuffer();
outBuf.Add(new TypedValue((short)LispDataType.ListBegin));
if (splitDoitBuffer(inBuf, ref _args, ref _buf))
{
outBuf.Add(new TypedValue((short)LispDataType.Int32, _args.Count));
outBuf.Add(new TypedValue((short)LispDataType.Int32, _buf.Count));
}
outBuf.Add(new TypedValue((short)LispDataType.ListEnd));
return outBuf;
}
static bool splitDoitBuffer(ResultBuffer inBuf, ref List<Point3d> _args, ref List<List<Point3d>> _buf)
{
bool isArg = true;
bool isInList = false;
_buf = new List<List<Point3d>>();
List<Point3d> subbuf = new List<Point3d>();
foreach (TypedValue typedValue in inBuf)
{
switch ((LispDataType)typedValue.TypeCode)
{
case LispDataType.ListBegin:
isInList = true;
break;
case LispDataType.ListEnd:
if (subbuf.Count > 0)
{
if (isArg)
{
_args = new List<Point3d>(subbuf);
isArg = false;
}
else
{
_buf.Add(new List<Point3d>(subbuf));
}
subbuf.Clear();
}
isInList = false;
break;
case LispDataType.Point3d:
if (isInList)
subbuf.Add((Point3d)typedValue.Value);
break;
}
}
return (_args != null && _args.Count != 0 && _buf.Count != 0);
}
}
Why, if you already have a valid lisp function? If you’re looking for performance, you may not get it as passing ResultBuffers to .NET is pretty heavy
You need to parse the ResultBuffer using TypedValue’s TypeCode property, here’s a quick example
(setq a (list (list 500 400 3.3) (list 600 700 2.3) (list 800 600 2.3)))
(setq b (list (list (list 500 400 3.3) (list 800 600 2.3) (list 500 400 3.3)) (list (list 600 700 2.3) (list 500 400 3.3) (list 800 600 2.3))))
(FOREACH tr b
(SETQ c (CONS (LIST (VL-POSITION (CAR tr) a)
(VL-POSITION (CADR tr) a)
(VL-POSITION (CADDR tr) a)) c)))
((1 0 2) (0 2 0)) => expected result
[LispFunction("GetPositions")]
public ResultBuffer GetPositions(ResultBuffer inBuf)
{
List<Point3d> _args = null;
List<List<Point3d>> _buf = null;
List<int> _outs = null;
ResultBuffer outBuf = new ResultBuffer();
outBuf.Add(new TypedValue((int)LispDataType.ListBegin));
if (splitDoitBuffer(inBuf, ref _args, ref _buf))
{
//outBuf.Add(new TypedValue((int)LispDataType.Int32, _args.Count));
//outBuf.Add(new TypedValue((int)LispDataType.Int32, _buf.Count));
foreach (List<Point3d> lpt in _buf)
{
foreach (Point3d pt in lpt)
{
int i = _args.IndexOf(pt);
if (i != -1)
_outs.Add(i);
}
outBuf.Add(new TypedValue((int)LispDataType.Point3d, (new Point3d(_outs[0], _outs[1], _outs[2]))));
}
}
outBuf.Add(new TypedValue((int)LispDataType.ListEnd));
return outBuf;
}
static bool splitDoitBuffer(ResultBuffer inBuf, ref List<Point3d> _args, ref List<List<Point3d>> _buf)
{
bool isArg = true;
bool isInList = false;
_buf = new List<List<Point3d>>();
List<Point3d> subbuf = new List<Point3d>();
foreach (TypedValue typedValue in inBuf)
{
switch ((LispDataType)typedValue.TypeCode)
{
case LispDataType.ListBegin:
isInList = true;
break;
case LispDataType.ListEnd:
if (subbuf.Count > 0)
{
if (isArg)
{
_args = new List<Point3d>(subbuf);
isArg = false;
}
else
{
_buf.Add(new List<Point3d>(subbuf));
}
subbuf.Clear();
}
isInList = false;
break;
case LispDataType.Point3d:
if (isInList)
subbuf.Add((Point3d)typedValue.Value);
break;
}
}
return (_args != null && _args.Count != 0 && _buf.Count != 0);
}