Пример #1
0
        public override void CreateMesh()
        {
            var box    = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_BOX_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_BOX_COORDINATES, getColorArray(Net3dBool.DefaultCoordinates.DEFAULT_BOX_VERTICES.Length, Color.Red));
            var sphere = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_SPHERE_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_SPHERE_COORDINATES, getColorArray(Net3dBool.DefaultCoordinates.DEFAULT_SPHERE_VERTICES.Length, Color.Red));

            sphere.scale(0.68, 0.68, 0.68);

            var cylinder1 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES, getColorArray(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES.Length, Color.Green));

            cylinder1.scale(0.38, 1, 0.38);

            var cylinder2 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES, getColorArray(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES.Length, Color.Green));

            cylinder2.scale(0.38, 1, 0.38);
            cylinder2.rotate(Math.PI / 2, 0);

            var cylinder3 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES, getColorArray(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES.Length, Color.Green));

            cylinder3.scale(0.38, 1, 0.38);
            cylinder3.rotate(Math.PI / 2, 0);
            cylinder3.rotate(0, Math.PI / 2);

            //--

            //mesh = s;

            //--

//            var modeller = new Net3dBool.BooleanModeller(b, c1);
//            mesh = modeller.getDifference();

            //--

            var modeller = new Net3dBool.BooleanModeller(box, sphere);
            var tmp      = modeller.getIntersection();

            modeller = new Net3dBool.BooleanModeller(tmp, cylinder1);
            tmp      = modeller.getDifference();

            modeller = new Net3dBool.BooleanModeller(tmp, cylinder2);
            tmp      = modeller.getDifference();

            modeller = new Net3dBool.BooleanModeller(tmp, cylinder3);
            tmp      = modeller.getDifference();

            mesh = tmp;
        }
Пример #2
0
        public override void CreateMesh()
        {
            var start = DateTime.UtcNow;

            Console.Write("Generate mesh...");

            var box    = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_BOX_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_BOX_COORDINATES);
            var sphere = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_SPHERE_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_SPHERE_COORDINATES);

            sphere.scale(0.68, 0.68, 0.68);

            var cylinder1 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES);

            cylinder1.scale(0.38, 1, 0.38);

            var cylinder2 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES);

            cylinder2.scale(0.38, 1, 0.38);
            cylinder2.rotate(Math.PI / 2, 0);

            var cylinder3 = new Net3dBool.Solid(Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_VERTICES, Net3dBool.DefaultCoordinates.DEFAULT_CYLINDER_COORDINATES);

            cylinder3.scale(0.38, 1, 0.38);
            cylinder3.rotate(Math.PI / 2, 0);
            cylinder3.rotate(0, Math.PI / 2);

            var modeller = new Net3dBool.BooleanModeller(box, sphere);
            var tmp      = modeller.GetIntersection();

            modeller = new Net3dBool.BooleanModeller(tmp, cylinder1);
            tmp      = modeller.GetDifference();

            modeller = new Net3dBool.BooleanModeller(tmp, cylinder2);
            tmp      = modeller.GetDifference();

            modeller = new Net3dBool.BooleanModeller(tmp, cylinder3);
            tmp      = modeller.GetDifference();

            mesh = tmp;

            var elapsed = DateTime.UtcNow - start;

            Console.WriteLine("done.");
            Console.WriteLine("Consumed time: {0}", elapsed);
        }
Пример #3
0
        public static void BoolActionExecute(Component_MeshInSpace firstMeshInSpace, Component_MeshInSpace secondMeshInSpace, UndoMultiAction undo, DocumentInstance document, BoolActionEnum boolAction)
        {
            //the first operand of the union operation must be a single geometry, otherwise duplicate parts will be made.
            if (boolAction == BoolActionEnum.Union && 1 < firstMeshInSpace.Mesh.Value.GetComponents <Component_MeshGeometry>().Length)
            {
                MergeGeometries(firstMeshInSpace.Mesh, document, undo);
            }
            bool needUndoForNextActions = true;

            CommonFunctions.ConvertProceduralMeshGeometries(document, firstMeshInSpace.Mesh, undo, ref needUndoForNextActions);

            List <(Vector3F[] positions, int[] indices)> data1List = GetData(firstMeshInSpace);

            (Vector3F[] positions, int[] indices)data2 = MergeData(GetData(secondMeshInSpace));

            //convert the second mesh in space, to the transform of first mesh in space
            var matrix = firstMeshInSpace.Transform.Value.ToMatrix4().GetInverse() * secondMeshInSpace.Transform.Value.ToMatrix4();

            Net3dBool.Vector3[] vertices2 = new Net3dBool.Vector3[data2.positions.Length];
            for (int i = 0; i < data2.positions.Length; i++)
            {
                vertices2[i] = ToNet3DBoolVector3((matrix * data2.positions[i]).ToVector3F());
            }
            var operand2 = new Net3dBool.Solid(vertices2, data2.indices);

            var geometries         = firstMeshInSpace.Mesh.Value.GetComponents <Component_MeshGeometry>();
            var resultGeometries   = new List <(Vector3F[] positions, int[] indices, MeshData.MeshGeometryFormat format)>();
            var geometriesToDelete = new List <Component_MeshGeometry>();

            for (int geomIndex = 0; geomIndex < data1List.Count; geomIndex++)
            {
                var data1 = data1List[geomIndex];
                Net3dBool.Vector3[] vertices1 = data1.positions.Select(ToNet3DBoolVector3).ToArray();

                var modeller = new Net3dBool.BooleanModeller(new Net3dBool.Solid(vertices1, data1.indices), operand2);                     //Большую часть времени на вычисления занимает эта сторка

                Net3dBool.Solid result = null;
                switch (boolAction)
                {
                case BoolActionEnum.Union: result = modeller.GetUnion(); break;

                case BoolActionEnum.Intersect: result = modeller.GetIntersection(); break;

                case BoolActionEnum.Subtract: result = modeller.GetDifference(); break;

                default: return;
                }

                var newVertices = result.getVertices().Select(ToVector3F).ToArray();
                if (0 < newVertices.Length)
                {
                    resultGeometries.Add((newVertices, result.getIndices(), new MeshData.MeshGeometryFormat(geometries[geomIndex].VertexStructure)));
                }
                else
                {
                    geometriesToDelete.Add(geometries[geomIndex]);
                }
            }

            foreach (var g in resultGeometries)
            {
                if (!CheckValid(g.positions, g.indices))
                {
                    throw new Exception();
                }
            }

            //delete empty mesh geometry //
            if (0 < geometriesToDelete.Count)
            {
                undo?.AddAction(new UndoActionComponentCreateDelete(document, geometriesToDelete.ToArray(), create: false));
            }

            var meshData = MeshData.BuildFromRaw(resultGeometries);

            meshData?.Save(firstMeshInSpace.Mesh.Value, needUndoForNextActions ? undo : null, null);               //??? No selection?
            firstMeshInSpace.Mesh.Value?.RebuildStructure();
        }
Пример #4
0
        private StaticMeshComponent CreateMesh()
        {
            var mesh = Mesh.CreateCube().ToPrimitive(MeshFaceType.Triangle);

            mesh.CreateFacesAndIndicies();
            mesh.Scale(10);
            var ind  = mesh.GetIndiciesArray();
            var vert = mesh.GetComponent <MeshPosition3Component>().ToArray().Select(s => new Vector3d(s.X, s.Y, s.Z)).ToArray();
            var box  = new Net3dBool.Solid(vert, ind);

            mesh = Mesh.CreateCube().ToPrimitive(MeshFaceType.Triangle);
            mesh.CreateFacesAndIndicies();
            mesh.Scale(3);
            ind  = mesh.GetIndiciesArray();
            vert = mesh.GetComponent <MeshPosition3Component>().ToArray().Select(s => new Vector3d(s.X, s.Y, s.Z)).ToArray();
            var box2 = new Net3dBool.Solid(vert, ind);

            mesh = Mesh.CreateCube().ToPrimitive(MeshFaceType.Triangle);
            mesh.CreateFacesAndIndicies();
            mesh.Scale(2);
            mesh.Translate(1, 0, 0);
            ind  = mesh.GetIndiciesArray();
            vert = mesh.GetComponent <MeshPosition3Component>().ToArray().Select(s => new Vector3d(s.X, s.Y, s.Z)).ToArray();
            var box3 = new Net3dBool.Solid(vert, ind);

            var modeller = new Net3dBool.BooleanModeller(box, box2);
            var tmp      = modeller.GetDifference();

            modeller = new Net3dBool.BooleanModeller(tmp, box3);
            tmp      = modeller.GetDifference();

            VertexDataPosNormalColor[] data = tmp.GetVertices().Select(v => new VertexDataPosNormalColor(new Vector3((float)v.X, (float)v.Y, (float)v.Z), new Vector3(1, 0, 0), new Vector4(1, 1, 0, 1))).ToArray();
            for (var i = 0; i < data.Length; i++)
            {
                var face   = i / 3;
                var vertex = i % 3;
                // switch (vertex)
                // {
                //     case 0:
                //         data[i].Color = new Vector4(1, 0, 0, 1);
                //         break;
                //     case 1:
                //         data[i].Color = new Vector4(0, 1, 0, 1);
                //         break;
                //     case 2:
                //         data[i].Color = new Vector4(0, 0, 1, 1);
                //         break;
                // }
                data[i].Normal = Vector3.UnitX;
            }
            var meshData = Mesh.CreateFromVertices(data, tmp.GetIndices().ToArray());

            meshData.Expand();
            meshData.RecalculateNormals(25f);

            var material = new Material
            {
                Ambient        = 0.5f,
                Color          = new Vector4(1, 1, 1, 1),
                UseVertexColor = true,
                PipelineType   = PipelineType.Forward,
            };

            var comp = new StaticMeshComponent()
            {
                Name                = "BoolMesh",
                RelativeRotation    = new Vector3(0, 0, 0.5f).ToQuaternion(),
                RelativeScale       = new Vector3(1),
                RelativeTranslation = new Vector3(2, 0, 0.5f),
                Material            = material,
            };

            comp.SetMesh(meshData);
            return(comp);
        }
Пример #5
0
        // GROUPER::GENERATE
        public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica)
        {
            //if (ArchimatixUtils.doDebug)
            //Debug.Log (parametricObject.Name + " generate +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");


            if (!parametricObject.isActive)
            {
                return(null);
            }



            preGenerate();


            //GameObject go = null;

//			if (makeGameObjects && !parametricObject.combineMeshes)
//				go = ArchimatixUtils.createAXGameObject (parametricObject.Name, parametricObject);


            List <AXMesh> ax_meshes = new List <AXMesh> ();

            Net3dBool.BooleanModeller modeler;
            Net3dBool.Solid           resSolid = null;


            // BOUNDING

            List <AXMesh> boundingMeshes = new List <AXMesh> ();


//			List<Net3dBool.Solid> solids = new List<Net3dBool.Solid> ();
//			List<Net3dBool.Solid> voids = new List<Net3dBool.Solid> ();


            AXParameter        src_p  = null;
            AXParametricObject src_po = null;

            if (inputs != null && inputs.Count > 0)
            {
                Debug.Log("inputs.Count = " + inputs.Count);

                Mesh tmpMesh1 = new Mesh();
                Mesh tmpMesh2 = new Mesh();

                src_p = inputs [0].DependsOn;
                if (src_p != null)
                {
                    src_po = src_p.parametricObject;


                    CombineInstance[] combinator = new CombineInstance[src_po.Output.meshes.Count];
                    for (int bb = 0; bb < combinator.Length; bb++)
                    {
                        combinator [bb].mesh      = src_po.Output.meshes [bb].mesh;
                        combinator [bb].transform = src_po.Output.meshes [bb].transMatrix;
                    }
                    tmpMesh1 = new Mesh();
                    tmpMesh1.CombineMeshes(combinator);
                    tmpMesh1.RecalculateNormals();

//					Debug.Log("//////////////////");
//					for (int i = 0; i < tmpMesh1.vertices.Length; i++) {
//						Vector3 vert = tmpMesh1.vertices [i];
//						Debug.Log ("["+i+"] "+vert);
//
//					}
//					Debug.Log("//////////////////");
                }

                if (inputs.Count > 1 && inputs [1] != null)
                {
                    src_p = inputs [1].DependsOn;

                    if (src_p != null)
                    {
                        src_po = src_p.parametricObject;

                        if (src_po != null)
                        {
                            CombineInstance[] combinator = new CombineInstance[src_po.Output.meshes.Count];
                            for (int bb = 0; bb < combinator.Length; bb++)
                            {
                                combinator [bb].mesh      = src_po.Output.meshes [bb].mesh;
                                combinator [bb].transform = src_po.Output.meshes [bb].transMatrix;
                            }
                            tmpMesh2 = new Mesh();
                            tmpMesh2.CombineMeshes(combinator);
                            tmpMesh2.RecalculateNormals();



                            // convert to csg meshes
                            int len1 = tmpMesh1.vertices.Length;
                            Net3dBool.Point3d[] pverts1 = new Net3dBool.Point3d[len1];
                            Vector3             vert1;
                            for (int i = 0; i < len1; i++)
                            {
                                vert1 = tmpMesh1.vertices [i];

                                pverts1 [i] = new Net3dBool.Point3d(vert1.x, vert1.y, vert1.z);
                            }
                            Net3dBool.Solid a = new Net3dBool.Solid(pverts1,
                                                                    tmpMesh1.triangles,
                                                                    getColorArray(len1, Color.red));



                            // convert to csg meshes
                            int len2 = tmpMesh2.vertices.Length;
                            Net3dBool.Point3d[] pverts2 = new Net3dBool.Point3d[len2];
                            Vector3             vert2;
                            for (int i = 0; i < len2; i++)
                            {
                                vert2 = tmpMesh2.vertices [i];

                                pverts2[i] = new Net3dBool.Point3d(vert2.x, vert2.y, vert2.z);
                            }
                            Net3dBool.Solid b = new Net3dBool.Solid(pverts2,
                                                                    tmpMesh2.triangles,
                                                                    getColorArray(len2, Color.red));



                            modeler  = new Net3dBool.BooleanModeller(a, b);
                            resSolid = modeler.getDifference();



                            Mesh tmesh = new Mesh();
                            int  mlen  = resSolid.getVertices().Length;
                            Net3dBool.Point3d[] bverts = resSolid.getVertices();

                            Vector3[] vertices = new Vector3[mlen];

                            for (int i = 0; i < mlen; i++)
                            {
                                Net3dBool.Point3d p = bverts [i];
                                vertices [i] = new Vector3((float)p.x, (float)p.y, (float)p.z);
                            }
                            tmesh.vertices = vertices;

                            tmesh.triangles = resSolid.getIndices();

                            tmesh.RecalculateNormals();



                            ax_meshes.Add(new AXMesh(tmesh));


                            parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica);
                        }
                    }
                    return(null);
                }



//
//				for (int ii = 0; ii < inputs.Count; ii++) {
//					src_p = inputs [ii].DependsOn;
//
//					if (src_p == null)
//						continue;
//
//					Debug.Log ("ii=" + ii + ": " + src_p.Name);
//
//					if (src_p != null) {
//						src_po = src_p.parametricObject;
//
//
//						if (src_po.is3D ()) {
//							if (src_po.Output != null && src_po.Output.meshes != null) {
//								for (int j = 0; j < src_po.Output.meshes.Count; j++) {
//
//									int len = src_po.Output.meshes [j].mesh.vertices.Length;
//
//									// convert to csg meshes
//									Net3dBool.Point3d[] pverts = new Net3dBool.Point3d[len];
//									Vector3 vert;
//									for (int i = 0; i < len; i++) {
//										vert = src_po.Output.meshes [j].mesh.vertices [i];
//
//										pverts [i] = new Net3dBool.Point3d (vert.x, vert.y, vert.z);
//									}
//
//									if (ii == 0) {
//										solids.Add (new Net3dBool.Solid (pverts,
//											src_po.Output.meshes [j].mesh.triangles,
//											getColorArray (len, Color.red)));
//									} else {
//										voids.Add (new Net3dBool.Solid (pverts,
//											src_po.Output.meshes [j].mesh.triangles,
//											getColorArray (len, Color.red)));
//
//									}
//
//									Mesh tmesh = new Mesh ();
//									int mlen = resSolid.getVertices ().Length;
//									Net3dBool.Point3d[] bverts = resSolid.getVertices ();
//
//									Vector3[] vertices = new Vector3[mlen];
//
//									for (int i = 0; i < mlen; i++) {
//										Net3dBool.Point3d p = bverts [i];
//										vertices [i] = new Vector3 ((float)p.x, (float)p.y, (float)p.z);
//									}
//									tmesh.vertices = vertices;
//
//									tmesh.triangles = resSolid.getIndices ();
//
//									tmesh.RecalculateNormals ();
//
//
//									AXMesh dep_amesh = src_po.Output.meshes [j];
//									ax_meshes.Add (dep_amesh.Clone (dep_amesh.transMatrix));
//								}
//							}
//
//
//						}
//					}
//
//				}



                //now have all our solids and voids

//				Debug.Log (solids.Count + " -- " + voids.Count);
//
//				if (solids.Count == 0 || voids.Count == 0)
//					return null;
//
//
//				for (int ss=2; ss<solids.Count; ss++)
//					{
//						modeler = new Net3dBool.BooleanModeller (resSolid, solids [1]);
//						resSolid = modeler.getUnion();
//					}
//
//				if (solids.Count == 1) {
//					modeler = new Net3dBool.BooleanModeller (solids [0], voids [0]);
//					resSolid = modeler.getDifference ();
//
//					if (voids.Count > 1) {
//						for (int v = 1; v < voids.Count; v++) {
//							modeler = new Net3dBool.BooleanModeller (resSolid, voids [v]);
//							resSolid = modeler.getDifference ();
//						}
//					}
//				}
//				else
//				{
//					modeler = new Net3dBool.BooleanModeller (solids [0], solids [1]);
//					resSolid = modeler.getUnion();					for (int ss=2; ss<solids.Count; ss++)
//					{
//						modeler = new Net3dBool.BooleanModeller (resSolid, solids [1]);
//						resSolid = modeler.getUnion();
//					}
//
//					for (int ss=2; ss<solids.Count; ss++)
//					{
//						modeler = new Net3dBool.BooleanModeller (resSolid, solids [ss]);
//						resSolid = modeler.getUnion();
//					}
//					for (int vv=0; vv<voids.Count; vv++)
//					{
//						modeler = new Net3dBool.BooleanModeller (resSolid, voids[vv]);
//						resSolid = modeler.getDifference();
//					}
//
//				}
//
//				if (resSolid == null)
//					return null;
//
//				Mesh tmesh = new Mesh ();
//				int mlen = resSolid.getVertices ().Length;
//				Net3dBool.Point3d[] bverts = resSolid.getVertices ();
//
//				Vector3[] vertices = new Vector3[mlen];
//
//				for (int i = 0; i < mlen; i++) {
//					Net3dBool.Point3d p = bverts [i];
//					vertices [i] = new Vector3 ((float)p.x, (float)p.y, (float)p.z);
//				}
//				tmesh.vertices = vertices;
//
//				tmesh.triangles = resSolid.getIndices ();
//
//				tmesh.RecalculateNormals ();
//



                // BOUNDING MESHES
                //boundsCombinator[i].mesh      = input_p.DependsOn.parametricObject.boundsMesh;
                //boundsCombinator[i].transform     = input_p.DependsOn.parametricObject.generator.localMatrixWithAxisRotationAndAlignment;
//				if (src_po.boundsMesh != null)
//					boundingMeshes.Add (new AXMesh (src_po.boundsMesh, src_po.generator.localMatrixWithAxisRotationAndAlignment));


                // GAME_OBJECTS

//						if (makeGameObjects && !parametricObject.combineMeshes) {
//
//							GameObject plugGO = src_po.generator.generate (true, initiator_po, isReplica);
//							if (plugGO != null)
//								plugGO.transform.parent = go.transform;
//						}

                //ax_meshes.Add (new AXMesh (tmesh));


                //P_Output.meshes = src_p.meshes;



                // FINISH AX_MESHES


                //Debug.Log("ORG: " + ax_meshes.Count);
                parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica);



                // FINISH BOUNDS

                CombineInstance[] boundsCombinator = new CombineInstance[boundingMeshes.Count];
                for (int bb = 0; bb < boundsCombinator.Length; bb++)
                {
                    boundsCombinator [bb].mesh      = boundingMeshes [bb].mesh;
                    boundsCombinator [bb].transform = boundingMeshes [bb].transMatrix;
                }
                setBoundsWithCombinator(boundsCombinator);


                if (P_BoundsX != null && !P_BoundsX.hasRelations() && !P_BoundsX.hasExpressions())
                {
                    P_BoundsX.FloatVal = parametricObject.bounds.size.x;
                }

                if (P_BoundsY != null && !P_BoundsY.hasRelations() && !P_BoundsY.hasExpressions())
                {
                    P_BoundsY.FloatVal = parametricObject.bounds.size.y;
                }

                if (P_BoundsZ != null && !P_BoundsZ.hasRelations() && !P_BoundsZ.hasExpressions())
                {
                    P_BoundsZ.FloatVal = parametricObject.bounds.size.z;
                }
            }



            // FINISH GAME_OBJECTS

//			if (makeGameObjects) {
//				if (parametricObject.combineMeshes) {
//					go = parametricObject.makeGameObjectsFromAXMeshes (ax_meshes, true, false);
//
//
//					// COMBINE ALL THE MESHES
//					CombineInstance[] combine = new CombineInstance[ax_meshes.Count];
//
//					int combineCt = 0;
//					for (int i = 0; i < ax_meshes.Count; i++) {
//						AXMesh _amesh = ax_meshes [i];
//						combine [combineCt].mesh = _amesh.mesh;
//						combine [combineCt].transform = _amesh.transMatrix;
//						combineCt++;
//					}
//
//					Mesh combinedMesh = new Mesh ();
//					combinedMesh.CombineMeshes (combine);
//
//					// If combine, use combined mesh as invisible collider
//					MeshFilter mf = (MeshFilter)go.GetComponent (typeof(MeshFilter));
//
//					if (mf == null)
//						mf = (MeshFilter)go.AddComponent (typeof(MeshFilter));
//
//					if (mf != null) {
//						mf.sharedMesh = combinedMesh;
//						parametricObject.addCollider (go);
//					}
//				} else {
//					Matrix4x4 tmx = parametricObject.getLocalMatrix ();
//
//					go.transform.rotation = AXUtilities.QuaternionFromMatrix (tmx);
//					go.transform.position = AXUtilities.GetPosition (tmx);
//					go.transform.localScale = parametricObject.getLocalScaleAxisRotated ();
//				}
//				return go;
//			}



            return(null);
        }