Exemple #1
0
    public static void display(float imagesize = 64, AXNodeGraphEditorWindow editor = null)
    {
        //Debug.Log("imagesise="+imagesize);
        // called from an OnGUI
        //imagesize = 64;
        scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUIStyle.none, GUIStyle.none);

        EditorGUILayout.BeginVertical();

        string[] itemStrings = null;

        // Select menu item list
        if (editor.OutputParameterBeingDragged == null)
        {
            if (editor.model != null && editor.model.selectedPOs.Count > 1)
            {
                //if (editor.model.selectedPOs[0].is2D())
                //	itemStrings = ArchimatixEngine.nodeStringsFrom2DMultiSelect;

                //else
                itemStrings = ArchimatixEngine.nodeStringsFromMultiSelect;
            }
            else
            {
                itemStrings = ArchimatixEngine.nodeStrings;
            }
        }
        else if (editor.OutputParameterBeingDragged.parametricObject.is2D())
        {
            itemStrings = ArchimatixEngine.nodeStringsFrom2DOutput;
        }

        else if (editor.OutputParameterBeingDragged.parametricObject.is3D())
        {
            if (editor.OutputParameterBeingDragged.Type == AXParameter.DataType.Spline)
            {
                itemStrings = ArchimatixEngine.nodeStringsFrom2DOutput;
            }
            else
            {
                itemStrings = ArchimatixEngine.nodeStringsFrom3DOutput;
            }
        }
        else if (editor.OutputParameterBeingDragged.parametricObject.generator is RepeaterTool)
        {
            itemStrings = ArchimatixEngine.nodeStringsFromRepeaterTool;
        }


        /*
         * if (Library.last2DItem != null)
         * {
         *      if (GUILayout.Button(new GUIContent(Library.last2DItem.icon, Library.last2DItem.po.Name), new GUILayoutOption[] {GUILayout.Width(imagesize), GUILayout.Height(imagesize)}))
         *      {
         *
         *      }
         * }
         */


        List <string> stringList = null;

        if (itemStrings != null)
        {
            stringList = itemStrings.ToList();
        }

        if (stringList != null)
        {
            stringList.AddRange(Archimatix.customNodeNames);
        }

        // Build Menu
        string poName;

        if (stringList != null)
        {
            for (int i = 0; i < stringList.Count; i++)
            {
                string nodeName = stringList[i];

                Texture2D nodeIcon = null;


                if (ArchimatixEngine.nodeIcons.ContainsKey(nodeName))
                {
                    nodeIcon = ArchimatixEngine.nodeIcons[nodeName];
                }
                else
                {
                    if (ArchimatixEngine.nodeIcons.ContainsKey("CustomNode"))
                    {
                        nodeIcon = ArchimatixEngine.nodeIcons["CustomNode"];
                    }
                    else
                    {
                        continue;
                    }
                }



                if (nodeIcon != null)
                {
                    if (GUILayout.Button(new GUIContent(nodeIcon, nodeName), new GUILayoutOption[] { GUILayout.Width(imagesize), GUILayout.Height(imagesize) }))
                    {
                        //if (editor.DraggingOutputParameter != null)
                        //{
                        AXModel model = AXEditorUtilities.getOrMakeSelectedModel();

                        Undo.RegisterCompleteObjectUndo(model, "Node Menu Selection");

                        AXParametricObject mostRecentPO = model.recentlySelectedPO;


                        int index = nodeName.IndexOf("_");

                        poName = (index > 0) ? nodeName.Substring(0, index) : nodeName;

                        // Support multi-select operation
                        List <AXParametricObject> selectedPOs = new List <AXParametricObject>();
                        if (model.selectedPOs.Count > 0)
                        {
                            selectedPOs.AddRange(model.selectedPOs);
                        }



                        // ADD NEW PO TO MODEL (only this new po is selected after this)
                        AXParametricObject po = AXEditorUtilities.addNodeToCurrentModel(poName, false);

                        if (po == null || po.generator == null)
                        {
                            return;
                        }


                        float max_x = -AXGeometryTools.Utilities.IntPointPrecision;


                        if (poName == "FreeCurve")
                        {
                            ArchimatixEngine.sceneViewState = ArchimatixEngine.SceneViewState.AddPoint;
                        }



                        // DRAGGING A PARAMETER? THEN RIG'R UP!
                        if (editor.OutputParameterBeingDragged != null)
                        {
                            AXParametricObject draggingPO  = editor.OutputParameterBeingDragged.parametricObject;
                            AXParameter        new_input_p = null;

                            switch (nodeName)
                            {
                            case "Instance2D":
                            case "ShapeOffsetter":
                                po.getParameter("Input Shape").makeDependentOn(editor.OutputParameterBeingDragged);
                                po.intValue("Axis", editor.OutputParameterBeingDragged.parametricObject.intValue("Axis"));

                                if (po.geometryControls != null)
                                {
                                    po.geometryControls.isOpen = true;
                                }
                                break;

                            case "ShapeDistributor":
                                List <AXParameter> deps = new List <AXParameter>();

                                for (int dd = 0; dd < editor.OutputParameterBeingDragged.Dependents.Count; dd++)
                                {
                                    deps.Add(editor.OutputParameterBeingDragged.Dependents[dd]);
                                }

                                for (int dd = 0; dd < deps.Count; dd++)
                                {
                                    deps[dd].makeDependentOn(po.getParameter("Output Shape"));
                                }

                                po.getParameter("Input Shape").makeDependentOn(editor.OutputParameterBeingDragged);
                                po.intValue("Axis", editor.OutputParameterBeingDragged.parametricObject.intValue("Axis"));

                                if (po.geometryControls != null)
                                {
                                    po.geometryControls.isOpen = true;
                                }
                                break;

                            case "ShapeMerger":
                                po.generator.getInputShape().addInput().makeDependentOn(editor.OutputParameterBeingDragged);
                                if (editor.OutputParameterBeingDragged.axis != Axis.NONE)
                                {
                                    po.intValue("Axis", (int)editor.OutputParameterBeingDragged.axis);
                                }
                                else
                                {
                                    po.intValue("Axis", editor.OutputParameterBeingDragged.parametricObject.intValue("Axis"));
                                }

                                break;

                            case "PlanRepeater2D":
                            case "PlanRepeater2D_Corner":
                                po.getParameter("Corner Shape").makeDependentOn(editor.OutputParameterBeingDragged);
                                po.intValue("Axis", editor.OutputParameterBeingDragged.parametricObject.intValue("Axis"));
                                break;

                            case "PlanRepeater_Corner":
                                po.getParameter("Corner Mesh").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;


                            case "PairRepeater2D":
                            case "RadialRepeater2D":
                            case "RadialRepeater2D_Node":
                            case "LinearRepeater2D":
                            case "LinearRepeater2D_Node":
                            case "GridRepeater2D":
                            case "GridRepeater2D_Node":
                                po.getParameter("Node Shape").makeDependentOn(editor.OutputParameterBeingDragged);
                                po.intValue("Axis", editor.OutputParameterBeingDragged.parametricObject.intValue("Axis"));
                                break;

                            case "RadialRepeater2D_Cell":
                            case "LinearRepeater2D_Cell":
                            case "GridRepeater2D_Cell":
                                po.getParameter("Cell Shape").makeDependentOn(editor.OutputParameterBeingDragged);
                                po.intValue("Axis", editor.OutputParameterBeingDragged.parametricObject.intValue("Axis"));
                                break;

                            case "Grouper":
                                //po.addInputMesh().makeDependentOn(editor.OutputParameterBeingDragged);


                                po.addGroupee(editor.OutputParameterBeingDragged.parametricObject);

                                break;

                            case "PlanRepeater2D_Plan":
                            case "Polygon_Plan":
                            case "Extrude_Plan":
                            case "PlanSweep_Plan":
                            case "PlanRepeater_Plan":
                            case "PlanDeformer_Plan":

                                // SYNC AXES
                                if (editor.OutputParameterBeingDragged.axis != Axis.NONE)
                                {
                                    po.intValue("Axis", (int)editor.OutputParameterBeingDragged.axis);
                                }
                                else
                                {
                                    po.intValue("Axis", editor.OutputParameterBeingDragged.parametricObject.intValue("Axis"));
                                }


                                if (nodeName == "Extrude_Plan" && po.intValue("Axis") != (int)Axis.Y)
                                {
                                    po.floatValue("Bevel", 0);
                                }



                                // INSERT SHAPE_DISTRIBUTOR?
                                new_input_p = po.getParameter("Plan", "Input Shape");
                                //if (draggingPO.is2D() && !(draggingPO.generator is ShapeDistributor) && editor.OutputParameterBeingDragged.Dependents != null && editor.OutputParameterBeingDragged.Dependents.Count > 0)
                                //	model.insertShapeDistributor(editor.OutputParameterBeingDragged, new_input_p);
                                //else
                                new_input_p.makeDependentOn(editor.OutputParameterBeingDragged);

                                // the output of the new node should match the shapestate of the input
                                if (po.generator.P_Output != null)
                                {
                                    po.generator.P_Output.shapeState = new_input_p.shapeState;
                                }

                                AXNodeGraphEditorWindow.repaintIfOpen();

                                break;

                            case "Lathe_Section":
                            case "PlanSweep_Section":
                            case "PlanRepeater_Section":

                                //po.getParameter("Section").makeDependentOn(editor.OutputParameterBeingDragged);

                                // INSERT SHAPE_DISTRIBUTOR?
                                new_input_p = po.getParameter("Section");
                                if (draggingPO.is2D() && !(draggingPO.generator is ShapeDistributor) && draggingPO.hasDependents())
                                {
                                    model.insertShapeDistributor(editor.OutputParameterBeingDragged, new_input_p);
                                }
                                else
                                {
                                    new_input_p.makeDependentOn(editor.OutputParameterBeingDragged);
                                }

                                // the output of the new node should match the shapestate of the input
                                //if (po.generator.P_Output != null)
                                //Debug.Log(new_input_p.Name+" "+new_input_p.shapeState + " :=: " +editor.OutputParameterBeingDragged.Name + " " + editor.OutputParameterBeingDragged.shapeState);



                                AXNodeGraphEditorWindow.repaintIfOpen();


                                break;


                            case "NoiseDeformer":
                            case "ShearDeformer":
                            case "TwistDeformer":
                            case "DomicalDeformer":
                            case "TaperDeformer":
                            case "InflateDeformer":
                            case "PlanDeformer":

                                po.getParameter("Input Mesh").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;

                            //case "PlanDeformer_Plan":



                            case "PairRepeater":
                            case "StepRepeater":
                            case "RadialStepRepeater":

                                po.getParameter("Node Mesh").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;


                            case "LinearRepeater_Node":
                                AXParameter nodeMesh_p = po.getParameter("Node Mesh");
                                nodeMesh_p.makeDependentOn(editor.OutputParameterBeingDragged);

                                // if the src is very long in x, assume you want to repeat in Z
                                if (editor.OutputParameterBeingDragged.parametricObject.bounds.size.x > (6 * editor.OutputParameterBeingDragged.parametricObject.bounds.size.z))
                                {
                                    po.initiateRipple_setBoolParameterValueByName("zAxis", true);
                                }

                                break;

                            case "LinearRepeater_Cell":
                            case "PlanRepeater_Cell":
                                po.getParameter("Cell Mesh").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;

                            case "LinearRepeater_Span":
                                po.getParameter("Bay SpanU").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;


                            case "LinearRepeater":
                                po.getParameter("RepeaterU").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;

                            case "FloorRepeater":
                                po.getParameter("Floor Mesh").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;

                            case "RadialRepeater":
                            case "RadialRepeater_Node":
                            case "GridRepeater_Node":
                            case "PlanRepeater_Node":
                                po.getParameter("Node Mesh").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;

                            case "RadialRepeater_Span":
                            case "GridRepeater_Span":
                                po.getParameter("Bay SpanU", "SpanU Mesh").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;

                            case "GridRepeater_Cell":
                                po.getParameter("Cell Mesh").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;


                            case "ShapeRepeater_Plan":
                                AXEditorUtilities.addNodeToCurrentModel("ShapeRepeater").getParameter("Plan").makeDependentOn(editor.OutputParameterBeingDragged);
                                break;


                            default:
                                AXEditorUtilities.addNodeToCurrentModel(nodeName);
                                break;
                            }


                            if (editor.OutputParameterBeingDragged.parametricObject != null)
                            {
                                mostRecentPO = editor.OutputParameterBeingDragged.parametricObject;
                                //po.rect = editor.OutputParameterBeingDragged.parametricObject.rect;
                                //po.rect.x += 325;
                            }

                            /*
                             * else
                             * {
                             *      po.rect.x = (model.focusPointInGraphEditor.x)+100;// + UnityEngine.Random.Range(-100, 300);
                             *      po.rect.y = (model.focusPointInGraphEditor.y - 250) + UnityEngine.Random.Range(-10, 0);
                             * }
                             */
                        }



                        // NO DRAGGING - CONNECT ALL MULTI_SELECTED
                        else if (selectedPOs != null && selectedPOs.Count > 0)
                        {
                            switch (nodeName)
                            {
                            case "ShapeMerger":
                                AXShape shp = po.generator.getInputShape();
                                for (int j = 0; j < selectedPOs.Count; j++)
                                {
                                    AXParametricObject poo = selectedPOs [j];
                                    if (j == 0)
                                    {
                                        po.intValue("Axis", selectedPOs [j].intValue("Axis"));
                                    }
                                    max_x = Mathf.Max(max_x, poo.rect.x);
                                    if (poo.is2D())
                                    {
                                        AXParameter out_p = poo.generator.getPreferredOutputParameter();
                                        if (out_p != null)
                                        {
                                            shp.addInput().makeDependentOn(out_p);
                                        }
                                    }
                                }

                                po.rect.x = max_x + 250;
                                break;

                            case "Grouper":
                                //Debug.Log("selectedPOs="+selectedPOs.Count);

                                //if (model.currentWorkingGroupPO != null && ! selectedPOs.Contains(model.currentWorkingGroupPO))
                                //{
                                po.addGroupees(selectedPOs);

                                Rect r = AXUtilities.getBoundaryRectFromPOs(selectedPOs);
                                po.rect.x = r.center.x - po.rect.width / 2;
                                po.rect.y = r.center.y - po.rect.height / 2;
                                //}
                                //po.rect.x = max_x+250;
                                break;

                            case "Channeler":
                                //Debug.Log("selectedPOs="+selectedPOs.Count);

                                //if (model.currentWorkingGroupPO != null && ! selectedPOs.Contains(model.currentWorkingGroupPO))
                                //{
                                foreach (AXParametricObject selpo in selectedPOs)
                                {
                                    AXParameter inputer = po.addInputMesh();

                                    inputer.makeDependentOn(selpo.generator.P_Output);
                                }


                                Rect cr = AXUtilities.getBoundaryRectFromPOs(selectedPOs);
                                po.rect.x = cr.center.x - po.rect.width / 2;
                                po.rect.y = cr.center.y - po.rect.height / 2;
                                //}
                                //po.rect.x = max_x+250;
                                break;
                            }
                        }

                        else
                        {
                            switch (nodeName)
                            {
                            case "ShapeMerger":
                                po.assertInputControls();
                                //po.generator.getInputShape().addInput();
                                break;
                            }
                        }



                        editor.OutputParameterBeingDragged = null;
                        model.autobuild();

                        po.generator.adjustWorldMatrices();

                        if (mostRecentPO != null)
                        {
                            po.rect    = mostRecentPO.rect;
                            po.rect.x += (mostRecentPO.rect.width + 50);
                        }
                        else
                        {
                            po.rect.x = (model.focusPointInGraphEditor.x) + 100;                          // + UnityEngine.Random.Range(-100, 300);
                            po.rect.y = (model.focusPointInGraphEditor.y - 250) + UnityEngine.Random.Range(-10, 0);
                        }

                        po.rect.height = 700;

                        //AXNodeGraphEditorWindow.zoomToRectIfOpen(po.rect);


                        //model.beginPanningToRect(po.rect);
                    }
                }
            }
        }
        //GUILayout.Label (GUI.tooltip);


        EditorGUILayout.Space();
        EditorGUILayout.EndVertical();

        EditorGUILayout.EndScrollView();

        /* Not sure why I was doing this - it took up a huge amount of CPU!
         *
         *
         * editor.Repaint();
         * SceneView sv = SceneView.lastActiveSceneView;
         * if (sv != null)
         *      sv.Repaint();
         *
         */
    }
    public static int display(Rect pRect, AXNodeGraphEditorWindow editor, AXParameter p)
    {
        //Debug.Log("ParameterTextureGUI.DISPLAY "+p.Name);
        float cur_x = ArchimatixUtils.cur_x;
        //float box_w = ArchimatixUtils.paletteRect.width - cur_x - 3*ArchimatixUtils.indent;
        float box_w = pRect.width - cur_x - 1 * ArchimatixUtils.indent;

        int cur_y   = (int)pRect.y;
        int lineHgt = (int)pRect.height;
        int gap     = 5;



        //Color shapeColor = editor.getDataColor (AXParameter.DataType.Spline);

        Color dataColor = editor.getDataColor(p.Type);

        Color oldBackgroundColor = GUI.backgroundColor;

        GUI.backgroundColor = dataColor;


        // INPUT
        if (editor.OutputParameterBeingDragged == null || editor.OutputParameterBeingDragged.Type == p.Type)
        {
            if (p.PType != AXParameter.ParameterType.Output)
            {
                if (GUI.Button(new Rect(-3, cur_y, ArchimatixEngine.buttonSize, ArchimatixEngine.buttonSize), ""))
                {
                    if (editor.OutputParameterBeingDragged != null && editor.OutputParameterBeingDragged.Type != p.Type)
                    {
                        editor.OutputParameterBeingDragged = null;
                    }
                    else
                    {
                        editor.inputSocketClicked(p);
                    }
                }
            }
        }


        // OUTPUT

        if (editor.InputParameterBeingDragged == null || editor.InputParameterBeingDragged.Type == AXParameter.DataType.MaterialTool)
        {
            if (GUI.Button(new Rect(pRect.width + 6, cur_y, ArchimatixEngine.buttonSize, ArchimatixEngine.buttonSize), ""))
            {
                if (editor.InputParameterBeingDragged != null && editor.InputParameterBeingDragged.Type != p.Type)
                {
                    editor.InputParameterBeingDragged = null;
                }
                else
                {
                    editor.outputSocketClicked(p);
                }
            }
        }



        // LABEL BOX
        Rect boxRect = new Rect(cur_x + ArchimatixUtils.indent, cur_y, box_w, pRect.height);

        GUI.Box(boxRect, " "); GUI.Box(boxRect, " "); GUI.Box(boxRect, " "); GUI.Box(boxRect, " ");


        // LABEL
        Rect lRect = boxRect;

        lRect.x     += 3;
        lRect.width -= 10;
        GUI.Box(boxRect, " "); GUI.Box(boxRect, " "); GUI.Box(boxRect, " "); GUI.Box(boxRect, " ");

        GUIStyle labelstyle = GUI.skin.GetStyle("Label");

        labelstyle.alignment = TextAnchor.MiddleLeft;
        if (p.PType == AXParameter.ParameterType.Output)
        {
            labelstyle.alignment  = TextAnchor.MiddleRight;
            labelstyle.fixedWidth = lRect.width + 5;
        }

        string label = p.Name;

        if (p.ParentNode != null && p.ParentNode is AXShape)
        {
            if (p.DependsOn != null)
            {
                if (p.DependsOn.Parent != null)
                {
                    label = p.DependsOn.Parent.Name;
                }
            }
        }

        GUI.Label(lRect, label);



        // Texture Thumbnail
        AXParameter        src_p  = p.DependsOn;
        AXParametricObject src_po = null;

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

        Rect texThumbRect;

        if (src_po != null)
        {
            if (src_po.generator is MaterialTool && src_po.axMat.mat != null && src_po.axMat.mat.mainTexture != null)
            {
                texThumbRect = new Rect((boxRect.x + boxRect.width - lineHgt + 1), cur_y + 1, lineHgt - 2, lineHgt - 2);
                EditorGUI.DrawTextureTransparent(texThumbRect, src_po.axMat.mat.mainTexture, ScaleMode.ScaleToFit, 1.0F);
            }
            else
            {
                texThumbRect = new Rect((boxRect.x + boxRect.width - lineHgt + 1), cur_y + 1, lineHgt - 2, lineHgt - 2);
                EditorGUI.DrawTextureTransparent(texThumbRect, ArchimatixEngine.nodeIcons[p.Type.ToString()], ScaleMode.ScaleToFit, 1.0F);
            }
        }
        else if (src_po == null)
        {
            if (src_p != null)
            {
                texThumbRect = new Rect((boxRect.x + boxRect.width - lineHgt + 1), cur_y + 1, lineHgt - 2, lineHgt - 2);
                EditorGUI.DrawTextureTransparent(texThumbRect, ArchimatixEngine.nodeIcons[p.Type.ToString()], ScaleMode.ScaleToFit, 1.0F);
            }
            else
            {
                // NEW TOOL

                texThumbRect = new Rect((boxRect.x + boxRect.width - lineHgt), cur_y - 1, lineHgt, lineHgt);

                if (GUI.Button(texThumbRect, ArchimatixEngine.nodeIcons[p.Type.ToString()]))                   //"+"))
                {
                    src_po             = AXEditorUtilities.addNodeToCurrentModel(p.Type.ToString());
                    src_po.Name        = Regex.Replace(p.Name, @"\s+", "");                     // remove spaces
                    src_po.rect.x      = p.parametricObject.rect.x - 220;
                    src_po.rect.y      = p.parametricObject.rect.y + 50;
                    src_po.rect.height = 500;


                    if (p.parametricObject.model.currentWorkingGroupPO != null)
                    {
                        p.parametricObject.model.currentWorkingGroupPO.addGroupee(src_po);
                    }
                    else
                    {
                        src_po.grouper    = null;
                        src_po.grouperKey = null;
                    }



                    //AXNodeGraphEditorWindow.zoomToRectIfOpen(src_po.rect);
                    //src_po.inputControls.isOpen = true;

                    src_po.geometryControls.isOpen = true;

                    src_po.generator.pollInputParmetersAndSetUpLocalReferences();

                    //Debug.Log("here " + src_po.getParameter("Output"));

                    p.makeDependentOn(src_po.getParameter("Output"));

                    p.parametricObject.model.remapMaterialTools();

                    p.parametricObject.isAltered = true;
                    p.parametricObject.model.autobuild();
                }
            }
        }



        /*
         * // FOLDOUT (isOpen)
         * GUI.backgroundColor = new Color(1,1,1,1f);
         *
         * EditorGUI.BeginChangeCheck ();
         * p.isOpen = EditorGUI.Foldout (new Rect (cur_x, cur_y, 55, lineHgt), p.isOpen, "");
         * if (EditorGUI.EndChangeCheck ())
         * {
         *      if (src_p == null)
         *      {
         *              src_po = AXEditorUtilities.addNodeToCurrentModel(p.Type.ToString(), false);
         *              src_po.Name = Regex.Replace(p.Name, @"\s+", "");	// remove spaces
         *              src_po.rect.x = p.parametricObject.rect.x - 200;
         *              src_po.rect.y = p.parametricObject.rect.y + 50;
         *              src_po.isOpen = false;
         *              p.makeDependentOn(src_po.generator.P_Output);
         *              p.parametricObject.model.autobuild();
         *      }
         * }
         * GUI.backgroundColor = shapeColor;
         *
         * if (p.DependsOn == null)
         *      p.isOpen = false;
         *
         * cur_y += lineHgt+gap;
         *
         * if (p.isOpen)
         * {
         *
         *
         *
         *      //Archimatix.cur_x += Archimatix.indent;
         *      p.drawClosed = false;
         *
         *      Rect tRect = pRect;
         *      tRect.x = 20;//30;
         *      tRect.width = pRect.width;
         *      tRect.x += 2;
         *      tRect.width -= 11;
         *
         *      if (! src_po.isOpen)
         *      {
         *      foreach (AXParameter sp in src_po.getAllParametersOfPType(AXParameter.ParameterType.GeometryControl))
         *      {
         *
         *
         *
         *
         *
         *              tRect.y = cur_y;
         *              Rect cntlRect = tRect; // new Rect(x0, cur_y, wid, 16);
         *
         *
         *              int hgt = ParameterGUI.OnGUI(cntlRect, editor, sp);
         *
         *              cur_y += hgt + gap;
         *      }
         *      }
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *      //Archimatix.cur_x -= Archimatix.indent;
         *
         *
         *
         * }
         */
        cur_y += lineHgt + gap;

        GUI.backgroundColor = oldBackgroundColor;

        return(cur_y);
    }
    // INSTANCE
    public static AXParametricObject instancePO(AXParametricObject po)
    {
        // make an instance

        AXParametricObject src_po = po;


        if (po.is2D())
        {
            AXParameter output_p = po.generator.P_Output;
            if (output_p == null && po.generator is ShapeMerger)
            {
                ShapeMerger gener = (ShapeMerger)po.generator;



                output_p = gener.S_InputShape.getSelectedOutputParameter();
            }

            if (output_p != null)
            {
                AXParametricObject instance_po = AXEditorUtilities.addNodeToCurrentModel("Instance2D", true, po);

                AXParameter in_p = po.getParameter("Input Shape");

                if (in_p == null)
                {
                    src_po = po;
                }
                else if (in_p.DependsOn != null)
                {
                    src_po = in_p.DependsOn.parametricObject;
                }

                AXParameter out_p = src_po.getParameter("Output Shape");

                AXParameter inst_inP = instance_po.getParameter("Input Shape");

                inst_inP.makeDependentOn(out_p);

                inst_inP.shapeState = out_p.shapeState;

                AXParameter inst_outP = instance_po.getParameter("Output Shape");
                inst_outP.shapeState = out_p.shapeState;

                return(instance_po);
            }
        }
        else
        {
            if (src_po.generator is IReplica)
            {
                // get next PO from downstream
                AXParameter in_p = po.getParameter("Input Mesh");

                if (in_p.DependsOn != null)
                {
                    src_po = in_p.DependsOn.parametricObject;
                }
            }

            AXParameter out_p = src_po.getParameter("Output Mesh", "Output");

            if (out_p != null)
            {
                AXParametricObject instance_po = AXEditorUtilities.addNodeToCurrentModel("Instance", true, src_po);


                instance_po.getParameter("Input Mesh").makeDependentOn(out_p);



                return(instance_po);
            }
        }
        return(null);
    }
    public static void contextMenu(AXParameter p, Vector2 position)
    {
        AXModel model = p.parametricObject.model;

        GenericMenu menu = new GenericMenu();

        //parametricObject.generator.addContextMenuItems(menu);
        menu.AddSeparator("Organizers ...");
        menu.AddItem(new GUIContent("Grouper"), false, () => {
            AXParametricObject npo = AXEditorUtilities.addNodeToCurrentModel("Grouper");
            AXParameter new_p      = npo.addInputMesh();
            new_p.makeDependentOn(p);

            model.isAltered(21);
        });


        menu.AddSeparator(" ");
        menu.AddSeparator("Repeaters ...");
        menu.AddItem(new GUIContent("Instance"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("Instance").getParameter("Input Mesh").makeDependentOn(p);  model.autobuild();
        });
        menu.AddItem(new GUIContent("Replicant"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("Replicant").getParameter("Input Mesh").makeDependentOn(p);  model.autobuild();
        });

        menu.AddItem(new GUIContent("PairRepeater"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("PairRepeater").getPreferredInputParameter().makeDependentOn(p); model.autobuild();
        });

        menu.AddItem(new GUIContent("RadialRepeater"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("RadialRepeater").getPreferredInputParameter().makeDependentOn(p); model.autobuild();
        });


        menu.AddItem(new GUIContent("FloorRepeater (Node)"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("FloorRepeater").getParameter("Node Mesh").makeDependentOn(p); model.autobuild();
        });
        menu.AddItem(new GUIContent("FloorRepeater (Node)"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("FloorRepeater").getParameter("Story Mesh").makeDependentOn(p); model.autobuild();
        });

        // GRID_REPEATER
        menu.AddItem(new GUIContent("GridRepeater (Node)"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("GridRepeater").getParameter("Node Mesh").makeDependentOn(p); model.autobuild();
        });
        menu.AddItem(new GUIContent("GridRepeater (Cell)"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("GridRepeater").getParameter("Cell Mesh").makeDependentOn(p); model.autobuild();
        });
        menu.AddItem(new GUIContent("GridRepeater (Span)"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("GridRepeater").getParameter("Bay Span").makeDependentOn(p); model.autobuild();
        });

        menu.AddItem(new GUIContent("ShapeRepeater (Node Mesh)"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("ShapeRepeater").getParameter("Node Mesh").makeDependentOn(p); model.autobuild();
        });
        menu.AddItem(new GUIContent("ShapeRepeater (Bay Span Mesh)"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("ShapeRepeater").getParameter("Bay Span Mesh").makeDependentOn(p); model.autobuild();
        });

        menu.AddItem(new GUIContent("ShapeRepeater (Corner Mesh)"), false, () => {
            AXEditorUtilities.addNodeToCurrentModel("ShapeRepeater").getParameter("Corner Mesh").makeDependentOn(p); model.autobuild();
        });


        menu.ShowAsContext();
    }