Example #1
0
        public override Value Evaluate(FSharpList <Value> args)
        {
            var   crv       = (Curve)((Value.Container)args[0]).Item;
            Face  face      = null;
            Solid tempSolid = null;
            Plane thisPlane = null;

            if (((Value.Container)args[1]).Item is Face)
            {
                face = (Autodesk.Revit.DB.Face)((Value.Container)args[1]).Item;
            }
            else if (((Value.Container)args[1]).Item is Plane)
            {
                thisPlane = ((Value.Container)args[1]).Item as Plane;
                // tesselate curve and find uv envelope in projection to the plane
                IList <XYZ> tessCurve      = crv.Tessellate();
                var         curvePointEnum = tessCurve.GetEnumerator();
                XYZ         corner1        = new XYZ();
                XYZ         corner2        = new XYZ();
                bool        cornersSet     = false;
                for (; curvePointEnum.MoveNext();)
                {
                    if (!cornersSet)
                    {
                        corner1    = curvePointEnum.Current;
                        corner2    = curvePointEnum.Current;
                        cornersSet = true;
                    }
                    else
                    {
                        for (int coord = 0; coord < 3; coord++)
                        {
                            if (corner1[coord] > curvePointEnum.Current[coord])
                            {
                                corner1 = new XYZ(coord == 0 ? curvePointEnum.Current[coord] : corner1[coord],
                                                  coord == 1 ? curvePointEnum.Current[coord] : corner1[coord],
                                                  coord == 2 ? curvePointEnum.Current[coord] : corner1[coord]);
                            }
                            if (corner2[coord] < curvePointEnum.Current[coord])
                            {
                                corner2 = new XYZ(coord == 0 ? curvePointEnum.Current[coord] : corner2[coord],
                                                  coord == 1 ? curvePointEnum.Current[coord] : corner2[coord],
                                                  coord == 2 ? curvePointEnum.Current[coord] : corner2[coord]);
                            }
                        }
                    }
                }

                double dist1    = thisPlane.Origin.DistanceTo(corner1);
                double dist2    = thisPlane.Origin.DistanceTo(corner2);
                double sizeRect = 2.0 * (dist1 + dist2) + 100.0;


                CurveLoop cLoop = new CurveLoop();
                for (int index = 0; index < 4; index++)
                {
                    double coord0 = (index == 0 || index == 3) ? -sizeRect : sizeRect;
                    double coord1 = (index < 2) ? -sizeRect : sizeRect;
                    XYZ    pnt0   = thisPlane.Origin + coord0 * thisPlane.XVec + coord1 * thisPlane.YVec;

                    double coord3 = (index < 2) ? sizeRect : -sizeRect;
                    double coord4 = (index == 0 || index == 3) ? -sizeRect : sizeRect;
                    XYZ    pnt1   = thisPlane.Origin + coord3 * thisPlane.XVec + coord4 * thisPlane.YVec;
                    Line   cLine  = dynRevitSettings.Revit.Application.Create.NewLineBound(pnt0, pnt1);
                    cLoop.Append(cLine);
                }
                List <CurveLoop> listCLoops = new List <CurveLoop> ();
                listCLoops.Add(cLoop);

                tempSolid = GeometryCreationUtilities.CreateExtrusionGeometry(listCLoops, thisPlane.Normal, 100.0);

                //find right face

                FaceArray facesOfExtrusion = tempSolid.Faces;
                for (int indexFace = 0; indexFace < facesOfExtrusion.Size; indexFace++)
                {
                    Face faceAtIndex = facesOfExtrusion.get_Item(indexFace);
                    if (faceAtIndex is PlanarFace)
                    {
                        PlanarFace pFace = faceAtIndex as PlanarFace;
                        if (Math.Abs(thisPlane.Normal.DotProduct(pFace.Normal)) < 0.99)
                        {
                            continue;
                        }
                        if (Math.Abs(thisPlane.Normal.DotProduct(thisPlane.Origin - pFace.Origin)) > 0.1)
                        {
                            continue;
                        }
                        face = faceAtIndex;
                        break;
                    }
                }
                if (face == null)
                {
                    throw new Exception("Curve Face Intersection could not process supplied Plane.");
                }
            }

            IntersectionResultArray xsects = new IntersectionResultArray();
            SetComparisonResult     result = face.Intersect(crv, out xsects);

            var xsect_results = FSharpList <Value> .Empty;
            var results       = FSharpList <Value> .Empty;

            if (xsects != null)
            {
                foreach (IntersectionResult ir in xsects)
                {
                    var xsect = FSharpList <Value> .Empty;
                    try
                    {
                        xsect = FSharpList <Value> .Cons(Value.NewNumber(ir.EdgeParameter), xsect);
                    }
                    catch
                    {
                        xsect = FSharpList <Value> .Cons(Value.NewNumber(0), xsect);
                    }
                    xsect = FSharpList <Value> .Cons(Value.NewContainer(ir.EdgeObject), xsect);

                    xsect = FSharpList <Value> .Cons(Value.NewNumber(ir.Parameter), xsect);

                    if (thisPlane != null)
                    {
                        UV planeUV = new UV(thisPlane.XVec.DotProduct(ir.XYZPoint - thisPlane.Origin),
                                            thisPlane.YVec.DotProduct(ir.XYZPoint - thisPlane.Origin));
                        xsect = FSharpList <Value> .Cons(Value.NewContainer(planeUV), xsect);
                    }
                    else
                    {
                        xsect = FSharpList <Value> .Cons(Value.NewContainer(ir.UVPoint), xsect);
                    }

                    xsect = FSharpList <Value> .Cons(Value.NewContainer(ir.XYZPoint), xsect);

                    xsect_results = FSharpList <Value> .Cons(Value.NewList(xsect), xsect_results);
                }
            }
            results = FSharpList <Value> .Cons(Value.NewList(xsect_results), results);

            results = FSharpList <Value> .Cons(Value.NewString(result.ToString()), results);

            return(Value.NewList(results));
        }
Example #2
0
        public override Value Evaluate(FSharpList <Value> args)
        {
            //unwrap the values
            IEnumerable <double> nvals = ((Value.List)args[0]).Item.Select(q => (double)((Value.Number)q).Item);

            var curve = (Curve)((Value.Container)args[1]).Item;

            sfm = (SpatialFieldManager)((Value.Container)args[2]).Item;

            if (!sfm.IsResultSchemaNameUnique(DYNAMO_TEMP_CURVES_SCHEMA, -1))
            {
                IList <int> arses = sfm.GetRegisteredResults();
                foreach (int i in arses)
                {
                    AnalysisResultSchema arsTest = sfm.GetResultSchema(i);
                    if (arsTest.Name == DYNAMO_TEMP_CURVES_SCHEMA)
                    {
                        schemaId = i;
                        break;
                    }
                }
            }
            else
            {
                var ars = new AnalysisResultSchema(DYNAMO_TEMP_CURVES_SCHEMA, "Temporary curves from Dynamo.");
                schemaId = sfm.RegisterResult(ars);
            }

            Transform trf = Transform.Identity;

            //http://thebuildingcoder.typepad.com/blog/2012/09/sphere-creation-for-avf-and-filtering.html#3

            var create = dynRevitSettings.Doc.Application.Application.Create;

            Transform t = curve.ComputeDerivatives(0, true);

            XYZ x = t.BasisX.Normalize();
            XYZ y = t.BasisX.IsAlmostEqualTo(XYZ.BasisZ) ?
                    t.BasisX.CrossProduct(XYZ.BasisY).Normalize() :
                    t.BasisX.CrossProduct(XYZ.BasisZ).Normalize();
            XYZ z = x.CrossProduct(y);

            Ellipse arc1 = dynRevitSettings.Revit.Application.Create.NewEllipse(t.Origin, .1, .1, y, z, -Math.PI, 0);
            Ellipse arc2 = dynRevitSettings.Revit.Application.Create.NewEllipse(t.Origin, .1, .1, y, z, 0, Math.PI);

            var pathLoop = new CurveLoop();

            pathLoop.Append(curve);
            var profileLoop = new CurveLoop();

            profileLoop.Append(arc1);
            profileLoop.Append(arc2);

            double curveDomain = curve.get_EndParameter(1) - curve.get_EndParameter(0);

            int idx = -1;
            var s   = GeometryCreationUtilities.CreateSweptGeometry(pathLoop, 0, 0, new List <CurveLoop> {
                profileLoop
            });

            foreach (Face face in s.Faces)
            {
                //divide the V domain by the number of incoming
                BoundingBoxUV domain = face.GetBoundingBox();
                double        vSpan  = domain.Max.V - domain.Min.V;

                //analysis values
                idx = sfm.AddSpatialFieldPrimitive(face, trf);

                //a list to hold the analysis points
                IList <UV> uvPts = new List <UV>();

                //a list to hold the analysis values
                IList <ValueAtPoint> valList = new List <ValueAtPoint>();

                //int count = nvals.Count();

                //this is creating a lot of sample points, but if we used less
                //sampling points, AVF would draw the two surfaces as if there was a hard
                //edge between them. this provides a better blend.
                int count = 10;
                for (int i = 0; i < count; i++)
                {
                    //get a UV point on the face
                    //find its XYZ location and project to
                    //the underlying curve. find the value which corresponds
                    //to the location on the curve
                    var uv  = new UV(domain.Min.U, domain.Min.V + vSpan / count * (double)i);
                    var uv1 = new UV(domain.Max.U, domain.Min.V + vSpan / count * (double)i);
                    uvPts.Add(uv);
                    uvPts.Add(uv1);

                    XYZ facePt                    = face.Evaluate(uv);
                    IntersectionResult ir         = curve.Project(facePt);
                    double             curveParam = curve.ComputeNormalizedParameter(ir.Parameter);

                    if (curveParam < 0)
                    {
                        curveParam = 0;
                    }

                    if (curveParam > 1)
                    {
                        curveParam = 1;
                    }

                    var valueIndex = (int)Math.Floor(curveParam * (double)nvals.Count());
                    if (valueIndex >= nvals.Count())
                    {
                        valueIndex = nvals.Count() - 1;
                    }

                    //create list of values at this point - currently supporting only one
                    //var doubleList = new List<double> { nvals.ElementAt(i) };
                    var doubleList = new List <double> {
                        nvals.ElementAt(valueIndex)
                    };

                    //add value at point object containing the value list
                    valList.Add(new ValueAtPoint(doubleList));
                    valList.Add(new ValueAtPoint(doubleList));
                }

                var pnts = new FieldDomainPointsByUV(uvPts);
                var vals = new FieldValues(valList);

                sfm.UpdateSpatialFieldPrimitive(
                    idx, pnts, vals, schemaId);

                idxs.Add(idx);
            }

            return(Value.NewNumber(idx));
        }
Example #3
0
        public override Value Evaluate(FSharpList<Value> args)
        {
            Transform t = (Transform)((Value.Container)args[0]).Item;
            double width = ((Value.Number)args[1]).Item;
            double height = ((Value.Number)args[2]).Item;

            //ccw from upper right
            XYZ p0 = new XYZ(width/2, width/2, 0);
            XYZ p1 = new XYZ(-width/2, width/2, 0);
            XYZ p2 = new XYZ(-width/2, -width/2, 0);
            XYZ p3 = new XYZ(width/2, -width/2, 0);

            p0 = t.OfPoint(p0);
            p1 = t.OfPoint(p1);
            p2 = t.OfPoint(p2);
            p3 = t.OfPoint(p3);

            Line l1 = dynRevitSettings.Doc.Application.Application.Create.NewLineBound(p0,p1);
            Line l2 = dynRevitSettings.Doc.Application.Application.Create.NewLineBound(p1,p2);
            Line l3 = dynRevitSettings.Doc.Application.Application.Create.NewLineBound(p2,p3);
            Line l4 = dynRevitSettings.Doc.Application.Application.Create.NewLineBound(p3,p0);

            CurveLoop cl = new CurveLoop();
            cl.Append(l1);
            cl.Append(l2);
            cl.Append(l3);
            cl.Append(l4);

            crvs.Add(l1);
            crvs.Add(l2);
            crvs.Add(l3);
            crvs.Add(l4);

            return Value.NewContainer(cl);
        }
Example #4
0
        public override Value Evaluate(FSharpList<Value> args)
        {
            var crv = (Curve)((Value.Container)args[0]).Item;
            Face face = null;
            Solid tempSolid = null;
            Plane thisPlane = null;

            if (((Value.Container)args[1]).Item is Face)
                face = (Autodesk.Revit.DB.Face)((Value.Container)args[1]).Item;
            else if (((Value.Container)args[1]).Item is Plane)
            {
                thisPlane = ((Value.Container)args[1]).Item as Plane;
                // tesselate curve and find uv envelope in projection to the plane
                IList<XYZ> tessCurve = crv.Tessellate();
                var curvePointEnum = tessCurve.GetEnumerator();
                XYZ corner1 = new XYZ();
                XYZ corner2 = new XYZ();
                bool cornersSet = false;
                for (; curvePointEnum.MoveNext(); )
                {
                    if (!cornersSet)
                    {
                        corner1 = curvePointEnum.Current;
                        corner2 = curvePointEnum.Current;
                        cornersSet = true;
                    }
                    else
                    {
                        for (int coord = 0; coord < 3; coord++)
                        {
                           if (corner1[coord] > curvePointEnum.Current[coord])
                              corner1 = new XYZ(coord == 0 ? curvePointEnum.Current[coord] : corner1[coord],
                                              coord == 1 ? curvePointEnum.Current[coord] : corner1[coord],
                                              coord == 2 ? curvePointEnum.Current[coord] : corner1[coord]);
                            if (corner2[coord] < curvePointEnum.Current[coord])
                               corner2 = new XYZ(coord == 0 ? curvePointEnum.Current[coord] : corner2[coord],
                                              coord == 1 ? curvePointEnum.Current[coord] : corner2[coord],
                                              coord == 2 ? curvePointEnum.Current[coord] : corner2[coord]);
                        }
                    }
                }

                double dist1 = thisPlane.Origin.DistanceTo(corner1);
                double dist2 = thisPlane.Origin.DistanceTo(corner2);
                double sizeRect = 2.0 * (dist1 + dist2) + 100.0;

                CurveLoop cLoop = new CurveLoop();
                for (int index = 0; index < 4; index++)
                {
                    double coord0 = (index == 0 || index == 3) ? -sizeRect : sizeRect;
                    double coord1 = (index < 2) ? -sizeRect : sizeRect;
                    XYZ pnt0 =  thisPlane.Origin + coord0 * thisPlane.XVec + coord1 * thisPlane.YVec;

                    double coord3 = (index < 2) ? sizeRect : -sizeRect;
                    double coord4 = (index == 0 || index == 3) ? -sizeRect : sizeRect;
                    XYZ pnt1 = thisPlane.Origin + coord3 * thisPlane.XVec + coord4 * thisPlane.YVec;
                    Line cLine = dynRevitSettings.Revit.Application.Create.NewLineBound(pnt0, pnt1);
                    cLoop.Append(cLine);
                }
                List<CurveLoop> listCLoops = new List<CurveLoop> ();
                listCLoops.Add(cLoop);

                tempSolid = GeometryCreationUtilities.CreateExtrusionGeometry(listCLoops, thisPlane.Normal, 100.0);

                //find right face

                FaceArray facesOfExtrusion = tempSolid.Faces;
                for (int indexFace = 0; indexFace < facesOfExtrusion.Size; indexFace++)
                {
                    Face faceAtIndex = facesOfExtrusion.get_Item(indexFace);
                    if (faceAtIndex is PlanarFace)
                    {
                        PlanarFace pFace = faceAtIndex as PlanarFace;
                        if (Math.Abs(thisPlane.Normal.DotProduct(pFace.Normal)) < 0.99)
                            continue;
                        if (Math.Abs(thisPlane.Normal.DotProduct(thisPlane.Origin - pFace.Origin)) > 0.1)
                            continue;
                        face = faceAtIndex;
                        break;
                    }
                }
                if (face == null)
                    throw new Exception("Curve Face Intersection could not process supplied Plane.");
            }

            IntersectionResultArray xsects = new IntersectionResultArray();
            SetComparisonResult result = face.Intersect(crv, out xsects);

            var xsect_results = FSharpList<Value>.Empty;
            var results = FSharpList<Value>.Empty;
            if (xsects != null)
            {
                foreach (IntersectionResult ir in xsects)
                {
                    var xsect = FSharpList<Value>.Empty;
                    try
                    {
                        xsect = FSharpList<Value>.Cons(Value.NewNumber(ir.EdgeParameter), xsect);
                    }
                    catch
                    {
                        xsect = FSharpList<Value>.Cons(Value.NewNumber(0), xsect);
                    }
                    xsect = FSharpList<Value>.Cons(Value.NewContainer(ir.EdgeObject), xsect);
                    xsect = FSharpList<Value>.Cons(Value.NewNumber(ir.Parameter), xsect);
                    if (thisPlane != null)
                    {
                        UV planeUV = new UV(thisPlane.XVec.DotProduct(ir.XYZPoint - thisPlane.Origin),
                                             thisPlane.YVec.DotProduct(ir.XYZPoint - thisPlane.Origin));
                        xsect = FSharpList<Value>.Cons(Value.NewContainer(planeUV), xsect);
                    }
                    else
                       xsect = FSharpList<Value>.Cons(Value.NewContainer(ir.UVPoint), xsect);

                    xsect = FSharpList<Value>.Cons(Value.NewContainer(ir.XYZPoint), xsect);
                    xsect_results = FSharpList<Value>.Cons(Value.NewList(xsect), xsect_results);
                }
            }
            results = FSharpList<Value>.Cons(Value.NewList(xsect_results), results);
            results = FSharpList<Value>.Cons(Value.NewString(result.ToString()), results);
            return Value.NewList(results);
        }
Example #5
0
        public override Value Evaluate(FSharpList<Value> args)
        {
            //unwrap the values
            IEnumerable<double> nvals = ((Value.List)args[0]).Item.Select(q => (double)((Value.Number)q).Item);

            var curve = (Curve)((Value.Container)args[1]).Item;
            sfm = (SpatialFieldManager)((Value.Container)args[2]).Item;

            if (!sfm.IsResultSchemaNameUnique(DYNAMO_TEMP_CURVES_SCHEMA, -1))
            {
                IList<int> arses = sfm.GetRegisteredResults();
                foreach (int i in arses)
                {
                    AnalysisResultSchema arsTest = sfm.GetResultSchema(i);
                    if (arsTest.Name == DYNAMO_TEMP_CURVES_SCHEMA)
                    {
                        schemaId = i;
                        break;
                    }
                }
            }
            else
            {
                var ars = new AnalysisResultSchema(DYNAMO_TEMP_CURVES_SCHEMA, "Temporary curves from Dynamo.");
                schemaId = sfm.RegisterResult(ars);
            }

            Transform trf = Transform.Identity;

            //http://thebuildingcoder.typepad.com/blog/2012/09/sphere-creation-for-avf-and-filtering.html#3

            var create = dynRevitSettings.Doc.Application.Application.Create;

            Transform t = curve.ComputeDerivatives(0, true);

            XYZ x = t.BasisX.Normalize();
            XYZ y = t.BasisX.IsAlmostEqualTo(XYZ.BasisZ) ?
                t.BasisX.CrossProduct(XYZ.BasisY).Normalize() :
                t.BasisX.CrossProduct(XYZ.BasisZ).Normalize();
            XYZ z = x.CrossProduct(y);

            Ellipse arc1 = dynRevitSettings.Revit.Application.Create.NewEllipse(t.Origin, .1, .1, y,z,-Math.PI, 0);
            Ellipse arc2 = dynRevitSettings.Revit.Application.Create.NewEllipse(t.Origin, .1, .1, y, z, 0, Math.PI);

            var pathLoop = new CurveLoop();
            pathLoop.Append(curve);
            var profileLoop = new CurveLoop();
            profileLoop.Append(arc1);
            profileLoop.Append(arc2);

            double curveDomain = curve.get_EndParameter(1) - curve.get_EndParameter(0);

            int idx = -1;
            var s = GeometryCreationUtilities.CreateSweptGeometry(pathLoop, 0, 0, new List<CurveLoop>{profileLoop});
            foreach (Face face in s.Faces)
            {
                //divide the V domain by the number of incoming
                BoundingBoxUV domain = face.GetBoundingBox();
                double vSpan = domain.Max.V - domain.Min.V;

                //analysis values
                idx = sfm.AddSpatialFieldPrimitive(face, trf);

                //a list to hold the analysis points
                IList<UV> uvPts = new List<UV>();

                //a list to hold the analysis values
                IList<ValueAtPoint> valList = new List<ValueAtPoint>();

                //int count = nvals.Count();

                //this is creating a lot of sample points, but if we used less
                //sampling points, AVF would draw the two surfaces as if there was a hard
                //edge between them. this provides a better blend.
                int count = 10;
                for (int i = 0; i < count; i ++)
                {
                    //get a UV point on the face
                    //find its XYZ location and project to
                    //the underlying curve. find the value which corresponds
                    //to the location on the curve
                    var uv = new UV(domain.Min.U, domain.Min.V + vSpan / count*(double) i);
                    var uv1 = new UV(domain.Max.U, domain.Min.V + vSpan / count * (double)i);
                    uvPts.Add(uv);
                    uvPts.Add(uv1);

                    XYZ facePt = face.Evaluate(uv);
                    IntersectionResult ir = curve.Project(facePt);
                    double curveParam = curve.ComputeNormalizedParameter(ir.Parameter);

                    if (curveParam < 0)
                        curveParam = 0;

                    if (curveParam > 1)
                        curveParam = 1;

                    var valueIndex = (int)Math.Floor(curveParam * (double)nvals.Count());
                    if (valueIndex >= nvals.Count())
                        valueIndex = nvals.Count() - 1;

                    //create list of values at this point - currently supporting only one
                    //var doubleList = new List<double> { nvals.ElementAt(i) };
                    var doubleList = new List<double> { nvals.ElementAt(valueIndex) };

                    //add value at point object containing the value list
                    valList.Add(new ValueAtPoint(doubleList));
                    valList.Add(new ValueAtPoint(doubleList));
                }

                var pnts = new FieldDomainPointsByUV(uvPts);
                var vals = new FieldValues(valList);

                sfm.UpdateSpatialFieldPrimitive(
                    idx, pnts, vals, schemaId);

                idxs.Add(idx);
            }

            return Value.NewNumber(idx);
        }
Example #6
0
        public override Value Evaluate(FSharpList<Value> args)
        {
            SpatialFieldManager sfm = ((Value.Container)args[1]).Item as SpatialFieldManager;

            //first, cleanup the old one
            if(idxs.Count > 0)
            {
                foreach (int idx in idxs)
                {
                    sfm.RemoveSpatialFieldPrimitive(idx);
                }
            }

            if (!sfm.IsResultSchemaNameUnique(DYNAMO_TEMP_CURVES_SCHEMA, -1))
            {
                IList<int> arses = sfm.GetRegisteredResults();
                foreach (int i in arses)
                {
                    AnalysisResultSchema arsTest = sfm.GetResultSchema(i);
                    if (arsTest.Name == DYNAMO_TEMP_CURVES_SCHEMA)
                    {
                        schemaId = i;
                        break;
                    }
                }
            }
            else
            {
                AnalysisResultSchema ars = new AnalysisResultSchema(DYNAMO_TEMP_CURVES_SCHEMA, "Temporary curves from Dynamo.");
                schemaId = sfm.RegisterResult(ars);
            }

            Transform trf = Transform.Identity;

            //get the list of pairs
            FSharpList<Value> listOfPairs = ((Value.List)args[0]).Item;
            foreach (Value expr in listOfPairs)
            {
                FSharpList<Value> pair = ((Value.List)expr).Item;

                XYZ start = (XYZ)((Value.Container)pair[0]).Item;
                XYZ end = (XYZ)((Value.Container)pair[1]).Item;
                XYZ start1 = start + XYZ.BasisZ * .1;
                XYZ end1 = end + XYZ.BasisZ * .1;

                //http://thebuildingcoder.typepad.com/blog/2012/09/sphere-creation-for-avf-and-filtering.html#3

                var create = dynRevitSettings.Doc.Application.Application.Create;

                Line l1 = create.NewLineBound(start, end);
                Line l2 = create.NewLineBound(end, end1);
                Line l3 = create.NewLineBound(end1, start1);
                Line l4 = create.NewLineBound(start1, start);

                List<CurveLoop> loops = new List<CurveLoop>();
                CurveLoop cl = new CurveLoop();
                cl.Append(l1);
                cl.Append(l2);
                cl.Append(l3);
                cl.Append(l4);
                loops.Add(cl);
                Solid s = GeometryCreationUtilities.CreateExtrusionGeometry(loops, (end-start).CrossProduct(start1-start), .01);

                foreach (Face face in s.Faces)
                {
                    int idx = sfm.AddSpatialFieldPrimitive(face, trf);

                    //need to use double parameters because
                    //we're drawing lines
                    IList<UV> uvPts = new List<UV>();
                    uvPts.Add(face.GetBoundingBox().Min);

                    FieldDomainPointsByUV pnts
                      = new FieldDomainPointsByUV(uvPts);

                    List<double> doubleList
                      = new List<double>();

                    doubleList.Add(0);

                    IList<ValueAtPoint> valList
                      = new List<ValueAtPoint>();

                    valList.Add(new ValueAtPoint(doubleList));

                    FieldValues vals = new FieldValues(valList);

                    sfm.UpdateSpatialFieldPrimitive(
                      idx, pnts, vals, schemaId);

                    idxs.Add(idx);
                }
            }

            return Value.NewList(Utils.SequenceToFSharpList(idxs.Select(x => Value.NewNumber(x))));
        }