public void display(float imagesize = 64, AXNodeGraphEditorWindow editor = null, string mode = "2D") // mode { //Debug.Log("imagesise="+imagesize); // called from an OnGUI //imagesize = 64; Event e = Event.current; scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUIStyle.none, GUIStyle.none); //StopWatch sw = new StopWatch(); EditorGUILayout.BeginVertical(); if (mode == "2D") { if (ArchimatixEngine.library != null && ArchimatixEngine.library.filteredResults != null) { // EACH 2D ITEM for (int i = 0; i < ArchimatixEngine.library.filteredResults.Count; i++) { // ** THE BIG CLICK 2D LibraryItem li = ArchimatixEngine.library.filteredResults [i]; if (!li.includeInSidebarMenu) { continue; } if (!li.is2D) { continue; } if (GUILayout.Button(new GUIContent(li.icon, li.Name), GUILayout.Width(imagesize), GUILayout.Height(imagesize))) { e.Use(); AXParametricObject prevSelectedPO = null; if (ArchimatixEngine.currentModel != null && ArchimatixEngine.currentModel.selectedPOs != null && ArchimatixEngine.currentModel.selectedPOs.Count > 0) { //foreach(AXParametricObject poo in ArchimatixEngine.currentModel.selectedPOs) // Debug.Log(" --- " + poo.Name); prevSelectedPO = ArchimatixEngine.currentModel.selectedPOs [ArchimatixEngine.currentModel.selectedPOs.Count - 1]; ArchimatixEngine.currentModel.deselectAll(); } AXParametricObject npo = Library.instantiateParametricObject(li.readIntoLibraryFromRelativeAXOBJPath); npo.generator.pollInputParmetersAndSetUpLocalReferences(); if (prevSelectedPO != null) { // AUTO-CONNECT TO A SELECTED SHAPE_MERGER ShapeMerger shapeMerger = null; Rect rect = new Rect(); if (prevSelectedPO != null && prevSelectedPO.generator is ShapeMerger) { shapeMerger = prevSelectedPO.generator as ShapeMerger; rect = new Rect(prevSelectedPO.rect.x - 300, prevSelectedPO.rect.y, prevSelectedPO.rect.width, prevSelectedPO.rect.height); } if (shapeMerger == null && prevSelectedPO.generator.P_Output != null) { foreach (AXParameter d in prevSelectedPO.generator.P_Output.Dependents) { if (d.parametricObject.generator is ShapeMerger) { shapeMerger = d.parametricObject.generator as ShapeMerger; rect = new Rect(prevSelectedPO.rect.x + 50, prevSelectedPO.rect.y + 50, prevSelectedPO.rect.width, prevSelectedPO.rect.height); break; } } } if (shapeMerger != null) { shapeMerger.connect(npo); npo.rect = rect; npo.generator.pollInputParmetersAndSetUpLocalReferences(); shapeMerger.pollInputParmetersAndSetUpLocalReferences(); ArchimatixEngine.currentModel.autobuild(); shapeMerger.adjustWorldMatrices(); npo.generator.adjustWorldMatrices(); //AXNodeGraphEditorWindow.zoomToRectIfOpen(npo.rect); } } if (npo != null) { if (npo.rect.width < npo.generator.minNodePaletteWidth) { npo.rect.width = npo.generator.minNodePaletteWidth; } } //Selection.activeGameObject = null; } } } } else { // 3D Library if (ArchimatixEngine.library != null && ArchimatixEngine.library.filteredResults != null) { for (int i = 0; i < ArchimatixEngine.library.filteredResults.Count; i++) { // THE BIG CLICK 3D !!!! LibraryItem li = ArchimatixEngine.library.filteredResults [i]; if (!li.includeInSidebarMenu) { continue; } if (li.is2D) { continue; } if (GUILayout.Button(new GUIContent(li.icon, li.Name), GUILayout.Width(imagesize), GUILayout.Height(imagesize))) { Library.instantiateParametricObject(li.readIntoLibraryFromRelativeAXOBJPath); //Selection.activeGameObject = null; } } } } EditorGUILayout.Space(); EditorGUILayout.EndVertical(); //Debug.Log(sw.stop()); 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(); * */ }
// SHAPE_REPEATER_2D :: GENERATE public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (parametricObject == null || !parametricObject.isActive) { return(null); } if ((P_Node == null || inputSrc_p == null) && (P_Cell == null || cellSrc_p == null)) { if (P_Output != null) { P_Output.paths = null; P_Output.polyTree = null; } return(null); } if (repeaterToolU == null) { return(null); } // PRE_GENERATE preGenerate(); AXParameter P_nodeOutput = new AXParameter(); P_nodeOutput.parametricObject = parametricObject; AXParameter P_cellOutput = new AXParameter(); P_cellOutput.parametricObject = parametricObject; // PROCESS NODE INPUT if (inputSrc_p != null) { P_Node.polyTree = null; AXShape.thickenAndOffset(ref P_Node, inputSrc_p); //P_nodeOutput.polyTree = null; //AXShape.thickenAndOffset(ref P_nodeOutput, P_Node); } if (cellSrc_p != null) { P_Cell.polyTree = null; AXShape.thickenAndOffset(ref P_Cell, cellSrc_p); //P_cellOutput.polyTree = null; //AXShape.thickenAndOffset(ref P_cellOutput, P_Cell); } bool doPolyTreeNodes = false; bool doPolyTreeCells = false; // NODE Matrix4x4 tm = Matrix4x4.identity; Paths tmpPaths = null; Clipper clipper = null; if (nodeSrc_p != null) { if (P_Node.polyTree != null && P_Output.shapeState == ShapeState.Closed) { tmpPaths = AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_Node.polyTree)); doPolyTreeNodes = true; clipper = new Clipper(); } else { tmpPaths = P_Node.getClonePaths(); P_nodeOutput.paths = new Paths(); } if (tmpPaths != null && tmpPaths.Count > 0) { for (int i = 0; i <= repeaterToolU.cells; i++) { //tm = Matrix4x4.TRS(new Vector3(2*i-2, 2*j-2, 0), Quaternion.identity, Vector3.one); tm = localMatrixFromAddress(RepeaterItem.Node, i); if (doPolyTreeNodes) { clipper.AddPaths(AX.Generators.Generator2D.transformPaths(tmpPaths, tm), PolyType.ptSubject, true); } else { Paths tmp = AX.Generators.Generator2D.transformPaths(tmpPaths, tm); P_nodeOutput.paths.AddRange(tmp); } } if (doPolyTreeNodes) { P_nodeOutput.polyTree = new AXClipperLib.PolyTree(); clipper.Execute(ClipType.ctDifference, P_nodeOutput.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero); } } } // CELL // PROCESS CELL INPUT if (cellSrc_p != null) { if (P_Cell.polyTree != null) { tmpPaths = AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_Cell.polyTree)); doPolyTreeCells = true; clipper = new Clipper(); } else { tmpPaths = P_Cell.getClonePaths(); P_cellOutput.paths = new Paths(); } if (tmpPaths != null && tmpPaths.Count > 0) { for (int i = 0; i < repeaterToolU.cells; i++) { tm = localMatrixFromAddress(RepeaterItem.Cell, i); if (doPolyTreeCells) { clipper.AddPaths(AX.Generators.Generator2D.transformPaths(tmpPaths, tm), PolyType.ptSubject, true); } else { Paths tmp = AX.Generators.Generator2D.transformPaths(tmpPaths, tm); P_cellOutput.paths.AddRange(tmp); } } if (doPolyTreeCells) { P_cellOutput.polyTree = new AXClipperLib.PolyTree(); clipper.Execute(ClipType.ctDifference, P_cellOutput.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero); } } } P_Output.polyTree = null; if (nodeSrc_p != null && (cellSrc_p == null || (P_cellOutput.paths == null && P_cellOutput.polyTree == null))) { // JUST NODES AXShape.thickenAndOffset(ref P_Output, P_nodeOutput); } else if (nodeSrc_p == null && cellSrc_p != null) { // JUST CELLS AXShape.thickenAndOffset(ref P_Output, P_cellOutput); } else { // BOTH TO COMBINE clipper = new Clipper(); if (P_nodeOutput.polyTree == null) { clipper.AddPaths(P_nodeOutput.paths, PolyType.ptSubject, true); } else { clipper.AddPaths(AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_nodeOutput.polyTree)), PolyType.ptSubject, true); } if (P_cellOutput.polyTree == null) { clipper.AddPaths(P_cellOutput.paths, PolyType.ptSubject, true); } else { clipper.AddPaths(AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_cellOutput.polyTree)), PolyType.ptSubject, true); } P_Output.polyTree = new AXClipperLib.PolyTree(); clipper.Execute(ClipType.ctUnion, P_Output.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero); AXShape.thickenAndOffset(ref P_Output, P_Output); } if (P_Output.polyTree != null) { transformPolyTree(P_Output.polyTree, localMatrix); } else if (P_nodeOutput.paths != null) { P_Output.paths = transformPaths(P_nodeOutput.paths, localMatrix); P_Output.transformedControlPaths = P_nodeOutput.paths; } //base.generate(false, initiator_po, isReplica); calculateBounds(); return(null); } // \generate
// GENERATE // This is the main function for generating a Shape, Mesh, or any other output that a node may be tasked with generating. // You can do pre processing of Inputs here, but that might best be done in an override of pollControlValuesFromParmeters(). // // Often, you will be creating a list of AXMesh objects. AXMesh has a Mesh, a Matrix4x4 and a Material // to be used when drawing the ouput to the scene before creating GameObjects. Your list of AXMeshes generated // is pased to the model via parametricObject.finishMultiAXMeshAndOutput(). // // When generate() is called by AX, it will be either with makeGameObjects set to true or false. // makeGameObjects=False is passed when the user is dragging a parameter and the model is regenerateing multiple times per second. // makeGameObjects=True is passed when the user has stopped editing (for example, OnMouseup from a Handle) and it is time to // build a GameObject hierarchy. public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (parametricObject == null || !parametricObject.hasInputMeshReady("Input Mesh")) { return(null); } // At this point the amount variable has been set to the FloatValue of its amount parameter. preGenerate(); // AXMeshes are the key product of a Generator3D List <AXMesh> ax_meshes = new List <AXMesh>(); AXParameter inputSrc_p = P_Input.DependsOn; AXParametricObject inputSrc_po = inputSrc_p.parametricObject; if (inputSrc_p != null && inputSrc_p.meshes != null) // Is there an input node connected to this node? { //Debug.Log("P_Input.DependsOn.meshes.Count="+P_Input.DependsOn.meshes.Count + ", "+ P_Input.DependsOn.meshes[0].GetType()); AXMesh amesh = null; // BOUNDING //CombineInstance[] boundsCombinator = new CombineInstance[ P_Input.DependsOn.meshes.Count]; // EACH MESH for (int i = 0; i < P_Input.DependsOn.meshes.Count; i++) { // Instance does not inhereit and build on the transform of its source object. amesh = P_Input.DependsOn.meshes [i].Clone(); Mesh m = amesh.mesh; Vector3[] verts = m.vertices; // ---------- EACH VERTEX ---------------------- for (int j = 0; j < verts.Length; j++) { Vector3 vert = new Vector3(verts[j].x, verts[j].y, verts[j].z); Vector3 ray = (vert - center); float mag = ray.magnitude; vert = P_Input.DependsOn.meshes[i].drawMeshMatrix.MultiplyPoint3x4(vert); //vert = new Vector3(vert.x, (vert.y+amount*vert.x)+scale, vert.z); vert = vert + (ray.normalized * (amount * .5f) / mag); verts [j] = P_Input.DependsOn.meshes[i].drawMeshMatrix.inverse.MultiplyPoint3x4(vert); } // ---------- EACH VERTEX ---------------------- m.vertices = verts; //amesh.mesh.RecalculateNormals(); ax_meshes.Add(amesh); } parametricObject.boundsMesh = ArchimatixUtils.meshClone(inputSrc_po.boundsMesh); Vector3[] boundsVerts = parametricObject.boundsMesh.vertices; // ---------- EACH VERTEX ---------------------- for (int j = 0; j < boundsVerts.Length; j++) { Vector3 vert = new Vector3(boundsVerts[j].x, boundsVerts[j].y, boundsVerts[j].z); //vert = P_Input.DependsOn.meshes[i].drawMeshMatrix.MultiplyPoint3x4(vert); float scale = modifierCurve.Evaluate(vert.x); boundsVerts [j] = new Vector3(vert.x, (vert.y + amount * vert.x) + scale, vert.z); //boundsVerts [j] = P_Input.DependsOn.meshes[i].drawMeshMatrix.inverse.MultiplyPoint3x4(vert); } // ---------- EACH VERTEX ---------------------- parametricObject.boundsMesh.vertices = boundsVerts; parametricObject.boundsMesh.RecalculateBounds(); //parametricObject.bounds = inputSrc_po.bounds; parametricObject.bounds = parametricObject.boundsMesh.bounds; parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); if (makeGameObjects) { return(parametricObject.makeGameObjectsFromAXMeshes(ax_meshes)); } } return(null); }
public static void processEventCommand(Event e, AXModel model) { if (e.type == EventType.ValidateCommand) { e.Use(); } //Debug.Log("-> processEventCommand 1: PROCESS COMMAND "+e.commandName); var view = SceneView.lastActiveSceneView; string focusedControlName = GUI.GetNameOfFocusedControl(); if (model != null) { // intercept this command and use for po's switch (e.commandName) { case "UndoRedoPerformed": //Debug.Log ("UndoRedoPerformed"); model.cleanGraph(); model.autobuild(); for (int i = 0; i < model.selectedPOs.Count; i++) { model.selectedPOs[i].generator.adjustWorldMatrices(); } // SCENEVIEW if (SceneView.lastActiveSceneView != null) { SceneView.lastActiveSceneView.Repaint(); } //model.setRenderMode( AXModel.RenderMode.GameObjects ); model.cacheThumbnails("AXGeometryTools.Utilities::processEventCommand::UndoRedoPerformed"); if (e.type != EventType.Repaint && e.type != EventType.Layout) { e.Use(); } break; case "SelectAll": Debug.Log("SelectAll"); model.selectAll(); e.Use(); break; case "Copy": //Debug.Log ("COPY ..."+ GUI.GetNameOfFocusedControl()); //Debug.Log ("buf: " + EditorGUIUtility.systemCopyBuffer); //Debug.Log("-"+focusedControlName+"-"); //Debug.Log((string.IsNullOrEmpty(focusedControlName) || !focusedControlName.Contains("_Text_"))); if (string.IsNullOrEmpty(focusedControlName) || !focusedControlName.Contains("_Text_")) { if (model.selectedPOs.Count > 0) { EditorGUIUtility.systemCopyBuffer = LibraryEditor.poWithSubNodes_2_JSON(model.selectedPOs[0], true); } if (e.type != EventType.Repaint && e.type != EventType.Layout) { e.Use(); } } break; case "Paste": //Debug.Log ("PASTE"); //Debug.Log(GUI.GetNameOfFocusedControl()); //if (string.IsNullOrEmpty(GUI.GetNameOfFocusedControl())) //{ Undo.RegisterCompleteObjectUndo(model, "Paste"); string focusedControlNameBeforePaste = GUI.GetNameOfFocusedControl(); if (string.IsNullOrEmpty(focusedControlNameBeforePaste) || !focusedControlNameBeforePaste.Contains("_Text_")) { model.deselectAll(); Library.pasteParametricObjectFromString(EditorGUIUtility.systemCopyBuffer); model.autobuild(); if (e.type != EventType.Repaint && e.type != EventType.Layout) { e.Use(); } } model.autobuild(); break; case "Duplicate": Undo.RegisterCompleteObjectUndo(model, "Duplicate"); //Debug.Log ("Duplicate Command"); if (model.selectedPOs.Count > 0) { AXParametricObject selectedPO = model.selectedPOs[0]; instancePO(selectedPO); } model.autobuild(); if (e.type != EventType.Repaint && e.type != EventType.Layout) { e.Use(); } break; case "Cut": Undo.RegisterCompleteObjectUndo(model, "Cut"); //EditorGUIUtility.systemCopyBuffer = JSONSerializersAX.allSelectedPOsAsJson(model); if (string.IsNullOrEmpty(focusedControlName) || !focusedControlName.Contains("_Text_")) { if (model.selectedPOs.Count > 0) { EditorGUIUtility.systemCopyBuffer = LibraryEditor.poWithSubNodes_2_JSON(model.selectedPOs[0], true); } if (e.shift) { model.deleteSelectedPOsAndInputs(); } else { model.deleteSelectedPOs(); } model.autobuild(); if (e.type != EventType.Repaint && e.type != EventType.Layout) { e.Use(); } } break; case "SoftDelete": case "Delete": //Debug.Log("DELETE"); // see if it is a selected point on a curve //if (ArchimatixEngine /* * FreeCurve selectedFreeCurve = null; * * if ( model.selectedPOs != null && model.selectedPOs.Count == 1 && model.selectedPOs[0] != null && model.selectedPOs[0].generator != null && model.selectedPOs[0].generator is FreeCurve) * { * selectedFreeCurve = (FreeCurve) model.selectedPOs[0].generator; * } * * if (selectedFreeCurve != null && selectedFreeCurve.selectedIndices != null && selectedFreeCurve.selectedIndices.Count > 0) * { * // delete points * selectedFreeCurve.deleteSelected(); * } */ // SELECTED POINTS TO DELETE? //Debug.Log("focusedControlName="+focusedControlName); if (string.IsNullOrEmpty(focusedControlName) || !focusedControlName.Contains("_Text_")) { bool foundSelectedPoints = false; if (model.activeFreeCurves.Count > 0) { for (int i = 0; i < model.activeFreeCurves.Count; i++) { FreeCurve gener = (FreeCurve)model.activeFreeCurves[i].generator; //Debug.Log("gener.hasSelectedPoints()="+gener.hasSelectedPoints()); if (gener.hasSelectedPoints()) { foundSelectedPoints = true; gener.deleteSelected(); } } } //Debug.Log("foundSelectedPoints="+foundSelectedPoints); if (foundSelectedPoints) { ArchimatixEngine.mouseIsDownOnHandle = false; } else if (e.shift) { Undo.RegisterCompleteObjectUndo(model, "Delete Nodes"); model.deleteSelectedPOsAndInputs(); } // [S.Darkwell: changed else to this else if to fix bug: "Fix pressing Delete key without Node selected still registers undo event" https://archimatixbeta.slack.com/files/s.darkwell/F1DJRQ3LL/fix_pressing_delete_key_without_node_selected_still_registers_undo_event.cs - 2016.06.02] else if (model.selectedPOs.Count > 0) { Undo.RegisterCompleteObjectUndo(model, "Delete Node"); model.deleteSelectedPOs(); } else if (model.selectedParameterInputRelation != null) { Undo.RegisterCompleteObjectUndo(model, "Delete Dependancy"); model.selectedParameterInputRelation.makeIndependent(); model.selectedParameterInputRelation = null; } else if (model.selectedRelationInGraph != null) { Undo.RegisterCompleteObjectUndo(model, "Delete Relation"); model.unrelate(model.selectedRelationInGraph); model.selectedRelationInGraph = null; } //Debug.Log("*********************************** DELETE"); model.remapMaterialTools(); model.autobuild(); //Debug.Log("caching here G"); model.cacheThumbnails(); e.Use(); } break; case "FrameSelected": if (view != null) { float framePadding = 400; if (model.selectedPOs == null || model.selectedPOs.Count == 0) { //model.selectAll(); model.selectAllVisibleInGroup(model.currentWorkingGroupPO); Rect allRect = AXUtilities.getBoundaryRectFromPOs(model.selectedPOs); allRect.x -= framePadding; allRect.y -= framePadding; allRect.width += framePadding * 2; allRect.height += framePadding * 2; AXNodeGraphEditorWindow.zoomToRectIfOpen(allRect); model.deselectAll(); } else if (model.selectedPOs.Count > 1) { Rect allRect = AXUtilities.getBoundaryRectFromPOs(model.selectedPOs); allRect.x -= framePadding; allRect.y -= framePadding; allRect.width += framePadding * 2; allRect.height += framePadding * 2; AXNodeGraphEditorWindow.zoomToRectIfOpen(allRect); } else { //frame first po AXParametricObject currPO = model.cycleSelectedPO; // model.selectedPOs[0]; if (currPO == null) { currPO = model.mostRecentlySelectedPO; } if (currPO == null && model.selectedPOs != null && model.selectedPOs.Count > 0) { currPO = model.selectedPOs[0]; } if (currPO == null) { currPO = model.selectFirstHeadPO(); } if (currPO != null) { Matrix4x4 m = model.transform.localToWorldMatrix * currPO.worldDisplayMatrix; // * currPO.getLocalMatrix(); if (m.isIdentity) { m = currPO.generator.localMatrix; } Vector3 position = m.MultiplyPoint(currPO.bounds.center); if (currPO.bounds.size.magnitude > .005 && currPO.bounds.size.magnitude < 10000) { view.LookAt(position, view.camera.transform.rotation, currPO.bounds.size.magnitude * 1.01f); } else { //Debug.Log("FrameSelected - select ParametricObjectObject bounds not good: "+currPO.bounds.size.magnitude); } //if (currPO.grouper != null ) //{ AXNodeGraphEditorWindow.displayGroupIfOpen(currPO.grouper); //} //model.beginPanningToPoint(currPO.rect.center); AXNodeGraphEditorWindow.zoomToRectIfOpen(currPO.rect); } } if (e.type != EventType.Repaint && e.type != EventType.Layout) { e.Use(); } } break; } } // EDITOR WINDOW ArchimatixEngine.repaintGraphEditorIfExistsAndOpen(); // SCENEVIEW if (view != null) { view.Repaint(); } lastCommand = e.commandName; }
/* READ_LIBRARY FROM FILES * If the cache is there, use it. * Otherwise... * Parse all the files in the Library data folder * and, using the head object, extract meta data and build indices. */ public void readLibraryFromFiles() { //Debug.Log("read library"); //StopWatch sw = new StopWatch(); /* Maintain a live list of all the files found * as head POs * */ parametricObjects = new List <AXParametricObject>(); libraryItems = new List <LibraryItem>(); DirectoryInfo info = new DirectoryInfo(Application.dataPath); FileInfo[] files = info.GetFiles("*.axobj", SearchOption.AllDirectories); //Debug.Log ("LIBRARY READ " + files.Length); try { //foreach (var filepathname in files) for (int i = 0; i < files.Length; i++) { //Debug.Log ("file: " + files[i].ToString()); string filepathname = files[i].ToString(); AX.SimpleJSON.JSONNode jn = AX.SimpleJSON.JSON.Parse(File.ReadAllText(filepathname)); AXParametricObject head_po = null; if (jn ["parametric_objects"] != null) { head_po = JSONSerializersAX.ParametricObjectFromJSON(jn ["parametric_objects"] [0]); } else { head_po = JSONSerializersAX.ParametricObjectFromJSON(jn [0]); } //head_po.readIntoLibraryFromPathname = filepathname; head_po.readIntoLibraryFromRelativeAXOBJPath = ArchimatixUtils.getRelativeFilePath(filepathname); parametricObjects.Add(head_po); libraryItems.Add(new LibraryItem(head_po)); } } catch (Exception ex) { Console.WriteLine(ex.Message); } rebuildTagListsFromExistingPOs(); cacheLibraryItems(); //Debug.Log ("LIBRARY READ IN "+sw.stop()+" MILLISECONDS " + parametricObjects.Count + " items."); }
// Update is called once per frame void Update() { if (!Application.isPlaying) { return; } bool byPlane = true; if (handle == null) { return; } AXParametricObject parametricObject = handle.parametricObject; // GET POSITION if (parametricObject.is2D()) { context = parametricObject.model.transform.localToWorldMatrix * parametricObject.worldDisplayMatrix; if (parametricObject.generator.hasOutputsConnected() || parametricObject.is2D()) { context *= parametricObject.generator.localMatrix.inverse; } else { context *= parametricObject.getAxisRotationMatrix().inverse *parametricObject.generator.localMatrix.inverse *parametricObject.getAxisRotationMatrix(); } } else { // GROUPER MATRIX NOT WORKING.... context = parametricObject.model.transform.localToWorldMatrix * parametricObject.generator.parametricObject.worldDisplayMatrix * (parametricObject.getAxisRotationMatrix() * parametricObject.generator.getLocalAlignMatrix()).inverse * parametricObject.generator.localMatrix.inverse; } // position handle by parmeters. positionHandleGameObject(); double h_diff = 0; double v_diff = 0; if (mouseIsDown) { if (Input.touchCount == 1) { // touch input - works better with deltaPosition var touch = Input.GetTouch(0); //var dx = touch.deltaPosition.x; h_diff = (100.0 / Screen.width) * touch.deltaPosition.x; v_diff = (100.0 / Screen.width) * touch.deltaPosition.y; } else { // 0 touches: must be mouse input h_diff = (5000 / Screen.width) * Input.GetAxis("Mouse X"); v_diff = (5000 / Screen.width) * Input.GetAxis("Mouse Y"); } h_diff /= 5; v_diff /= 5; //Debug.Log(h_diff +", " + v_diff); //using plane if (byPlane) { establishDrawingSurface(); //Vector3 prevPosition = transform.position; } // BASED ON PLANE Vector3 world_pos = transform.position; if (byPlane) { Vector3 hit_position3D = sampleHitPoint(); world_pos = hit_position3D - mouseDownDiff; transform.position = world_pos; } Vector3 localPosition = context.inverse.MultiplyPoint3x4(world_pos); //transform.position = world_pos; //if (transform.position != prevPosition) if (h_diff != 0 || v_diff != 0) { //Debug.Log("moved"); // Determine the orientation of the camera //The normal OperatingSystemFamily the handle plane //Debug.Log (lookV); float threshold = .707f; double diffX = -v_diff; double diffZ = h_diff; // This logic works with a normal vector if (!byPlane) { if (lookV.x > 0 && lookV.z < 0) { diffX = (1 - lookV.x) * h_diff - lookV.x * v_diff; diffZ = (1 + lookV.z) * h_diff - lookV.z * v_diff; } else if (lookV.x > 0 && lookV.z > 0) { diffX = -((lookV.x)) * h_diff - lookV.x * v_diff; diffZ = (1 + lookV.z) * h_diff - lookV.z * v_diff; } else if (lookV.x < 0 && lookV.z > 0) { diffX = (1 + lookV.x) * h_diff + lookV.x * v_diff; diffZ = (1 - lookV.z) * h_diff + lookV.z * v_diff; } else if (lookV.x > 0 && lookV.z > 0) { diffX = -((lookV.x)) * h_diff - (lookV.x) * v_diff; diffZ = (1 + lookV.z) * h_diff - lookV.z * v_diff; //(-lookV.x + lookV.z) * v_diff; } else if (lookV.z > threshold) // pointing forwards { diffX = -h_diff; diffZ = -v_diff; } else if (lookV.z < -threshold) { // pointing backwards diffX = h_diff; diffZ = v_diff; } else if (lookV.x > 0) { // pointing right diffX = -h_diff; diffZ = v_diff; } else { // pointing left diffX = v_diff; diffZ = -h_diff; } } AXHandle han = handle; string hanString = "han_y"; float posV = localPosition.y; if (parametricObject.is3D()) { hanString = "han_z"; posV = localPosition.z; } if (byPlane) { parametricObject.setVar("han_x", (localPosition.x)); if (parametricObject.is3D()) { parametricObject.setVar("han_z", world_pos.z); } else { parametricObject.setVar("han_y", localPosition.y); } } else { // Relative slide of cursor parametricObject.setVar("han_x", (localPosition.x + (float)diffX)); parametricObject.setVar(hanString, (posV + (float)diffZ)); } // From plane // parametricObject.setVar("han_x", localPosition.x); // parametricObject.setVar("han_y", localPosition.y); // parametricObject.setVar("han_z", localPosition.z); // EACH EXPRESSION for (int i = 0; i < han.expressions.Count; i++) { if (han.expressions [i] == "") { continue; } string expression = Regex.Replace(han.expressions [i], @"\s+", ""); string paramName = expression.Substring(0, expression.IndexOf("=")); string definition = expression.Substring(expression.IndexOf("=") + 1); //Debug.Log (param + " --- " + definition); try { if (parametricObject.getParameter(paramName).Type == AXParameter.DataType.Int) { parametricObject.initiateRipple_setIntValueFromGUIChange(paramName, Mathf.RoundToInt((float)parametricObject.parseMath(definition))); } else { parametricObject.initiateRipple_setFloatValueFromGUIChange(paramName, (float)parametricObject.parseMath(definition)); } } catch (System.Exception e) { parametricObject.codeWarning = "10. Handle error: Please check syntax of: \"" + definition + "\" " + e.Message; } } parametricObject.model.isAltered(); //parametricObject.model.autobuild(); } } }
public static void processEventCommandKeyDown(Event e, AXModel model) { switch (e.keyCode) { case KeyCode.L: if (model.selectedPOs != null && model.selectedPOs.Count == 1) { LibraryEditor.doSave_MenuItem(model.selectedPOs[0]); if (e.type != EventType.Repaint && e.type != EventType.Layout) { e.Use(); } } break; case KeyCode.V: // this paste waste uncaught by EventType.ExecuteCommand or EventType.ValidateCommand // beacuse alt or command were held down Undo.RegisterCompleteObjectUndo(model, "Paste"); if (e.shift) { if (e.alt) { model.duplicateSelectedPOs(); } else { model.replicateSelectedPOs(); } model.isAltered(6); if (e.type != EventType.Repaint && e.type != EventType.Layout) { e.Use(); } } break; case KeyCode.D: Undo.RegisterCompleteObjectUndo(model, "Duplicate"); Debug.Log("DUPLICATE.....KeyCode.D"); if (model.selectedPOs.Count > 0) { AXParametricObject selectedPO = model.selectedPOs[0]; if (e.shift) { replicatePO(selectedPO); } else if (e.alt) { duplicatePO(selectedPO); } else { Debug.Log("instancePO"); instancePO(selectedPO); } } // "Duplicate" is caught by the validateCommand and processed here in processEventCommand() model.isAltered(7); if (e.type != EventType.Repaint && e.type != EventType.Layout) { e.Use(); } break; case KeyCode.Backspace: string focusedControlName = GUI.GetNameOfFocusedControl(); if (string.IsNullOrEmpty(focusedControlName) || !focusedControlName.Contains("_Text_")) { Undo.RegisterCompleteObjectUndo(model, "Delete"); if (e.shift) { model.deleteSelectedPOsAndInputs(); } else { model.deleteSelectedPOs(); } model.isAltered(8); e.Use(); } break; } // Update EditorWindow ArchimatixEngine.repaintGraphEditorIfExistsAndOpen(); }
// GENERATE REPLICANT public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool renderToOutputParameter) { //Debug.Log ("===> " + parametricObject.Name + " generate"); if (parametricObject == null || !parametricObject.hasInputMeshReady("Input Mesh")) { return(null); } if (!parametricObject.isActive) { return(null); } preGenerate(); AXParameter input_p = parametricObject.getParameter("Input Mesh"); if (parametricObject == null || input_p == null || input_p.DependsOn == null) { return(null); } AXParametricObject src_po = input_p.DependsOn.Parent; if (src_po == null) { return(null); } Matrix4x4 srcLocalM = src_po.getLocalMatrix().inverse; // 1. cache source object List <AXParameter> geometryControlParameterList = parametricObject.getAllParametersOfPType(AXParameter.ParameterType.GeometryControl); src_po.cacheAndSetParameters(geometryControlParameterList); if (!makeGameObjects) { // 2. re_generate source PO with temporary values set by this Replicant src_po.generateOutputNow(false, parametricObject, false); // 3. Now that the input_sourcePO has been regenerated, // grab the temporaryOutputMeshes meshes // from the input sources and add them here List <AXMesh> ax_meshes = new List <AXMesh>(); if (src_po.temporaryOutputMeshes != null) { for (int mi = 0; mi < src_po.temporaryOutputMeshes.Count; mi++) { AXMesh amesh = src_po.temporaryOutputMeshes [mi]; ax_meshes.Add(amesh.Clone(srcLocalM * amesh.transMatrix)); } } parametricObject.finishMultiAXMeshAndOutput(ax_meshes); setBoundaryFromAXMeshes(ax_meshes); } // 4. Make GAME OBJECTS GameObject go = null; if (makeGameObjects) { go = src_po.generator.generate(true, initiator_po, false); go.name = src_po.Name + " Replicant"; AXGameObject axgo = go.GetComponent <AXGameObject>(); if (axgo != null) { axgo.makerPO_GUID = parametricObject.Guid; } } // 5. restore source object; as though we were never here! src_po.revertParametersFromCache(); // Turn ax_meshes into GameObjects if (makeGameObjects) { 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); }
/* * public override Matrix4x4 getLocalConsumerMatrixPerInputSocket(AXParametricObject input, AXParameter input_p=null) * { * Debug.Log("planSrc_po="+planSrc_po); * if (planSrc_po != null) * { * //Debug.Log(input.Name + " -- " + planSrc_po.Name); * if (planSrc_po!= null && input == planSrc_po) * return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(90, 0, 0), Vector3.one); * * //return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(-90, 0, 0), Vector3.one); * } * return Matrix4x4.identity; * } * * * // GET_LOCAL_CONSUMER_MATRIX_PER_INPUT_SOCKET * public override Matrix4x4 getLocalConsumerMatrixPerInputSocket(AXParametricObject input_po) * { * //Debug.Log ("input_po.Name=" + input_po.Name);// + " -- " + endCapHandleTransform); * // PLAN * if (input_po == planSrc_po) * return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(90, 0, 0), Vector3.one); * * * // SECTION * if (input_po == sectionSrc_po) * return sectionHandleTransform * Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(90, 0, 0), Vector3.one); * * // ENDCAP * if (P_EndCapMesh != null && P_EndCapMesh.DependsOn != null && input_po == P_EndCapMesh.DependsOn.Parent) * return endCapHandleTransform; * * return Matrix4x4.identity ; * } */ public override Matrix4x4 getLocalConsumerMatrixPerInputSocket(AXParametricObject input_po, AXParameter input_P) { // use shift too // use caller address if (input_po == null) { return(Matrix4x4.identity); } bool addressIsNull = (input_po.selectedConsumer == null || input_po.selectedConsumer != this.parametricObject || String.IsNullOrEmpty(input_po.selectedConsumerAddress)); if (input_P != null) { if (input_P.Name == "Plan") { return(Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(90, 0, 0), Vector3.one)); } if (input_P.Name == "Section") { //Debug.Log("the section ****"); //Debug.Log(sectionHandleTransform); return(sectionHandleTransform * Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(90, 0, 0), Vector3.one)); } } // PLAN if (input_po == planSrc_po) { return(Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(90, 0, 0), Vector3.one)); } // SECTION if (input_po == sectionSrc_po) { return(sectionHandleTransform * Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(90, 0, 0), Vector3.one)); } // PARSE ADDRESS Matrix4x4 optionalLocalM = Matrix4x4.identity; if (addressIsNull) { // set default address if (nodeSrc_po != null && input_po == nodeSrc_po) { input_po.selectedConsumerAddress = "node_0_0_0"; } else if (cellSrc_po != null && input_po == cellSrc_po) { input_po.selectedConsumerAddress = "cell_0_0_0"; } else if (cornerSrc_po != null && input_po == cornerSrc_po) { input_po.selectedConsumerAddress = "corner_0_0"; } optionalLocalM = input_po.getLocalMatrix() * input_po.getAxisRotationMatrix().inverse; } addressIsNull = (input_po.selectedConsumer == null || input_po.selectedConsumer != this.parametricObject || String.IsNullOrEmpty(input_po.selectedConsumerAddress)); if (!addressIsNull) { string[] address = input_po.selectedConsumerAddress.Split('_'); if (address.Length < 3) { return(Matrix4x4.identity); } string meshInput = address[0]; // e.g., "node", "cell", "spanU", "spanV", "corner" // Find out which input this caller is fed into Node Mesh, Bay Span or Cell Mesh? //Debug.Log(input_po.selectedConsumerAddress); // CORNER if (meshInput == "corner" && cornerSrc_po != null && input_po == cornerSrc_po) { int path_i = int.Parse(address[1]); int vert_i = int.Parse(address[2]); return(localMatrixFromAddress(RepeaterItem.Corner, path_i, vert_i) * optionalLocalM); } if (meshInput == "node" && nodeSrc_po != null && input_po == nodeSrc_po && address.Length == 4) { int path_i = int.Parse(address[1]); int subspline_i = int.Parse(address[2]); int node_i = int.Parse(address[3]); return(localMatrixFromAddress(RepeaterItem.Node, path_i, subspline_i, node_i) * optionalLocalM); } if (meshInput == "cell" && cellSrc_po != null && input_po == cellSrc_po && address.Length == 4) { int path_i = int.Parse(address[1]); int subspline_i = int.Parse(address[2]); int node_i = int.Parse(address[3]); return(localMatrixFromAddress(RepeaterItem.Cell, path_i, subspline_i, node_i) * optionalLocalM); } } return(Matrix4x4.identity); }
public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (parametricObject == null || !parametricObject.isActive) { return(null); } if (P_PrototypePlan == null || P_Prototype == null) { return(null); } preGenerate(); // PLAN planSrc_p = P_Plan.DependsOn; // getUpstreamSourceParameter(P_Plan); planSrc_po = (planSrc_p != null) ? planSrc_p.parametricObject : null; //Pather.printPaths(planSrc_p.getPaths()); P_Plan.polyTree = null; AXShape.thickenAndOffset(ref P_Plan, planSrc_p); planPaths = P_Plan.getPaths(); if (planPaths == null || planPaths.Count == 0) { return(null); } prototypePlanSrc_p = P_PrototypePlan.DependsOn; prototypePlanSrc_po = (prototypePlanSrc_p != null) ? prototypePlanSrc_p.parametricObject : null; prototypeSrc_p = P_Prototype.DependsOn; prototypePlanSrc_po = (prototypeSrc_p != null) ? prototypeSrc_p.parametricObject : null; if (prototypePlanSrc_p == null || prototypePlanSrc_po == null || prototypeSrc_po == null) { return(null); } AXParameter srcSrc_p = prototypePlanSrc_p; if (srcSrc_p == null) { return(null); } // AX_MESHES List <AXMesh> ax_meshes = new List <AXMesh>(); GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } Perlin perlin = new Perlin(); perlin.OctaveCount = 1; perlin.Frequency = .05f; GameObject replicant = null; //Debug.Log("planPaths.Count="+ planPaths.Count); AXParameter P_Height = prototypeSrc_po.getParameter("Height", "SizeY"); foreach (Path plan in planPaths) { // 1. cache source object //prototypeSrc_po.cacheParameterValues(); Paths tmpPaths = new Paths(); tmpPaths.Add(plan); IntPoint planCenter = AXGeometryTools.Utilities.getCenter(tmpPaths); Vector3 centerPt = AXGeometryTools.Utilities.IntPt2Vec3(planCenter); //Debug.Log("Center: " + centerPt); srcSrc_p.paths = tmpPaths; float area = ((float)Clipper.Area(plan)) / 1000000000; //Debug.Log(area); float perlinVal = (float)perlin.GetValue(centerPt); float h = 3 + 100 * (float)Math.Exp(-(.1f * area)) + 5 * perlinVal; // (float) perlin.GetValue(2,3,4); P_Height.initiateRipple_setFloatValueFromGUIChange(h); prototypeSrc_po.generator.pollControlValuesFromParmeters(); prototypeSrc_po.isAltered = true; //Debug.Log("generate REP of "+prototypeSrc_po.Name); foreach (AXParameter d in prototypePlanSrc_p.Dependents) { d.parametricObject.setAltered(); } // ** GENERATE REPLICANT ** // replicant = prototypeSrc_po.generateOutputNow(makeGameObjects, parametricObject, false); //Debug.Log(replicant); if (replicant != null) { replicant.transform.parent = go.transform; } AXParameter output_p = prototypeSrc_po.getParameter("Output Mesh"); foreach (AXMesh amesh in output_p.meshes) { ax_meshes.Add(amesh.Clone(amesh.transMatrix)); } } // FINISH AX_MESHES parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); if (makeGameObjects) { return(go); } return(null); }
// GENERATE PLAN_SWEEP public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool renderToOutputParameter) { if (parametricObject == null || !parametricObject.isActive) { return(null); } //Debug.Log("PlanSweep::generate()"); // RESULTING MESHES ax_meshes = new List <AXMesh>(); preGenerate(); // PLAN // The plan may have multiple paths. Each may generate a separate GO. if (P_Plan == null) { return(null); } planSrc_p = getUpstreamSourceParameter(P_Plan); planSrc_po = (planSrc_p != null) ? planSrc_p.parametricObject : null; if (planSrc_p == null || !planSrc_p.parametricObject.isActive) { return(null); } P_Plan.polyTree = null; AXShape.thickenAndOffset(ref P_Plan, planSrc_p); // SECTION // The plan may have multiple paths. Each may generate a separate GO. if (P_Section == null) { return(null); } sectionSrc_p = getUpstreamSourceParameter(P_Section); sectionSrc_po = (sectionSrc_p != null) ? sectionSrc_p.parametricObject : null; if (sectionSrc_p == null || !sectionSrc_p.parametricObject.isActive) { return(null); } P_Section.polyTree = null; if (lipTop > 0 && P_Section.shapeState == ShapeState.Open && sectionSrc_p.paths != null && sectionSrc_p.paths.Count == 1) { P_Section.paths = new Paths(); Path path = new Path(); foreach (IntPoint ip in sectionSrc_p.paths[0]) { path.Add(new IntPoint(ip.X, ip.Y)); } if (lipBottom > 0) { path.Insert(0, new IntPoint((path[0].X - lipBottom * AXGeometryTools.Utilities.IntPointPrecision), path[0].Y)); if (lipEdge > 0) { path.Insert(0, new IntPoint(path[0].X, (path[0].Y + lipEdge * AXGeometryTools.Utilities.IntPointPrecision))); } } if (lipTop > 0) { path.Add(new IntPoint((path[path.Count - 1].X - lipTop * AXGeometryTools.Utilities.IntPointPrecision), path[path.Count - 1].Y)); if (lipEdge > 0) { path.Add(new IntPoint((path[path.Count - 1].X), (path[path.Count - 1].Y - lipEdge * AXGeometryTools.Utilities.IntPointPrecision))); } } P_Section.paths.Add(path); } else { AXShape.thickenAndOffset(ref P_Section, sectionSrc_p); } //StopWatch sw = new StopWatch(); GameObject retGO = generateFirstPass(initiator_po, makeGameObjects, P_Plan, P_Section, Matrix4x4.identity, renderToOutputParameter); //Debug.Log("PlanSweep ============= Done: " + sw.duration()); // FINISH AX_MESHES parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter); // FINISH BOUNDING setBoundaryFromAXMeshes(ax_meshes); //adjustWorldMatrices(); return(retGO); }
// GENERATE FREE_CURVE public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { parametricObject.transMatrix = Matrix4x4.TRS(new Vector3(transX, transY, 0), Quaternion.Euler(0, 0, rotZ), new Vector3(1, 1, 1)); //Debug.Log ("IntPoint = " + parametricObject.ip.X + " --- " + parametricObject.TestInt); if (P_Output != null && parametricObject.curve != null) { //Curve transformedCurve = parametricObject.getTransformedCurve(); //Output.spline = Archimatix.curve2Spline (transformedCurve); // ControlPaths P_Output.controlPaths = new Paths(); // not to be altered in base postprocessing for offset and wallthick // use the "curve" to generate the source path // bezier experiment // EACH SEGMENT Path path = new Path(); for (int i = 0; i <= parametricObject.curve.Count - 1; i++) { if (i == parametricObject.curve.Count - 1 && P_Output.shapeState == ShapeState.Open) { break; } CurvePoint a = parametricObject.curve[i]; int next_i = (i == parametricObject.curve.Count - 1) ? 0 : i + 1; CurvePoint b = parametricObject.curve[next_i]; if (a.isPoint() && b.isPoint()) { if (i == 0) { path.Add(AXGeometryTools.Utilities.Vec2_2_IntPt(a.position)); } path.Add(AXGeometryTools.Utilities.Vec2_2_IntPt(b.position)); } else { int governor = 0; for (float t = 0; t <= (1 + .9f * timetick); t = t + timetick) { if (governor++ > 50) { Debug.Log("governor hit)"); break; } if (i == 0 || t > 0) { Vector2 pt = bezierValue(parametricObject.curve[i], parametricObject.curve[next_i], t); path.Add(AXGeometryTools.Utilities.Vec2_2_IntPt(pt)); } } } } /* * if (P_Output.shapeState == ShapeState.Closed && (parametricObject.curve[0] || parametricObject.curve[parametricObject.curve.Count-1].isBezierPoint())) * { * // draw last Bezier curve * * * } */ // path = Clipper.CleanPolygon(path, .01f); // if (path != null) // { // if (! Clipper.Orientation(path)) // path.Reverse(); // // } P_Output.controlPaths.Add(path); P_Output.transformedControlPaths = P_Output.getTransformedControlPaths(); P_Output.paths = P_Output.getTransformedControlPaths(); // may be altered before generate is over... P_Output.polyTree = null; base.generate(false, initiator_po, isReplica); } else { Debug.Log("no path"); } base.generate(false, initiator_po, isReplica); calculateBounds(); return(null); }
// GENERATE PAIR_REPEATER public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { //Debug.Log ("PairRepeater::Generate "); if (parametricObject == null || !parametricObject.isActive) { return(null); } preGenerate(); if ((nodeSrc_p == null || nodeSrc_p.meshes == null || nodeSrc_p.meshes.Count == 0) && (nodeSrc_po != null && !(nodeSrc_po.generator is PrefabInstancer))) { return(null); } if (P_Node == null || P_Node.DependsOn == null) { return(null); } GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } List <AXMesh> ax_meshes = new List <AXMesh>(); GameObject plugGO = null; if (makeGameObjects && !parametricObject.combineMeshes) { plugGO = nodeSrc_po.generator.generate(true, initiator_po, isReplica); if (plugGO == null) { return(null); } } float separationX = zAxis ? 0 : separation; float separationZ = zAxis ? -separation : 0; CombineInstance[] boundsCombinator = new CombineInstance[2]; // * RIGHT INSTANCE * // -------------------------------------------------------------------- // Right Instance is at Address 0... Matrix4x4 localPlacement_mx = localNodeMatrixFromAddress(0); // use submeshes for right instance // AX_MESHES for (int mi = 0; mi < P_Node.DependsOn.meshes.Count; mi++) { AXMesh dep_amesh = P_Node.DependsOn.meshes [mi]; ax_meshes.Add(dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix)); } // BOUNDING MESHES boundsCombinator[0].mesh = nodeSrc_po.boundsMesh; boundsCombinator[0].transform = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; // GAME_OBJECTS if (plugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(plugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = nodeSrc_po.getLocalScaleAxisRotated(); AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = "node_0"; } copyGO.name = copyGO.name + "_node_right"; copyGO.transform.parent = go.transform; } // * INVERSE (LEFT) INSTANCE // -------------------------------------------------------------------- // ***--- AX_MESHES - INVERSE (LEFT) ---*** translate = new Vector3(-separationX / 2, 0, -separationZ / 2); // LOCAL PLACEMENT localPlacement_mx = localNodeMatrixFromAddress(1); // use submeshes for left instance for (int mi = 0; mi < P_Node.DependsOn.meshes.Count; mi++) { // CLONE AXMesh dep_amesh = P_Node.DependsOn.meshes [mi]; AXMesh clone = dep_amesh.Clone(); // SYMETRICAL? if (symmetrical) { clone.mesh = AXMesh.freezeWithMatrix(dep_amesh.mesh, symmetryM * dep_amesh.transMatrix); clone.transMatrix = localPlacement_mx * symmetryM.inverse; } else { clone = dep_amesh.Clone(localPlacement_mx * symmetryM.inverse * dep_amesh.transMatrix); } // ADD TO AX_MESHES ax_meshes.Add(clone); } // BOUNDING MESHES boundsCombinator[1].mesh = nodeSrc_po.boundsMesh; boundsCombinator[1].transform = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; // *** --- INVERSE (LEFT) - GAME_OBJECT ---** if (plugGO != null && makeGameObjects && !parametricObject.combineMeshes) { // LOCAL PLACEMENT //Matrix4x4 mx = localPlacement_mx * symmetryM * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; Matrix4x4 mx = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; // GAME_OBJECT GameObject copyGO = (GameObject)GameObject.Instantiate(plugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); copyGO.transform.localScale = nodeSrc_po.getLocalScaleAxisRotated(); // SYMETRICAL? if (symmetrical) { copyGO.transform.localScale = copyGO.transform.localScale * -1; if (zAxis) { copyGO.transform.Rotate(0, 180, 180); } else { copyGO.transform.Rotate(180, 0, 0); } } // Force a refreshing of the colliders down the instatiatined hierachy // Based on a solution provided by pkamat here:http://forum.unity3d.com/threads/how-to-update-a-mesh-collider.32467/ foreach (MeshCollider mc in copyGO.GetComponentsInChildren <MeshCollider>()) { mc.sharedMesh = null; mc.sharedMesh = mc.gameObject.GetComponent <MeshFilter>().sharedMesh; } // ADD GAME_OBJECT AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = "node_1"; } copyGO.name = copyGO.name + "_node_left"; copyGO.transform.parent = go.transform; } GameObject.DestroyImmediate(plugGO); // 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); combinedMesh.RecalculateBounds(); // BOUNDARY - Use combined meshes for boundary setBoundsWithCombinator(boundsCombinator); /* * // BOUNDS & CENTER * * Vector3 margin = new Vector3(source_po.bounds.size.x, source_po.bounds.size.y, source_po.bounds.size.z); * Bounds b = new Bounds(); * b.size = new Vector3(separationX + margin.x, margin.y, separationZ + margin.z); * b.extents = b.size/2; * b.center = source_po.bounds.center;// + new Vector3(0, b.extents.y, 0); * * parametricObject.margin = margin; * parametricObject.bounds = b; */ // FINISH parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); // Turn ax_meshes into GameObjects if (makeGameObjects) { if (parametricObject.combineMeshes) { go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true, false); // 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); } } //Matrix4x4 tmx = parametricObject.generator.localMatrix; 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); }
public static void render(AXParametricObject po, bool makeTexture = false) { AXModel model = po.model; if (model == null) { return; } model.assertThumnailSupport(); // THUMBNAIL BACKGROUND COLOR if (po.generator != null && makeTexture) { model.thumbnailCamera.backgroundColor = po.generator.ThumbnailColor; } // WHY ARE THE THUMNAIL AND RenTex null? if (po.renTex == null) { //po.renTex = new RenderTexture(256, 256, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default); po.renTex = new RenderTexture(256, 256, 24); } if (!po.renTex.IsCreated()) { po.renTex.antiAliasing = 8; po.renTex.Create(); } //Debug.Log(po.renTex.sRGB); // This started giving an error in 5.3 and did not seem to be needed anyway! if (makeTexture) { RenderTexture.active = po.renTex; } model.thumbnailCamera.targetTexture = po.renTex; model.thumbnailCameraGO.transform.position = po.getThumbnailCameraPosition(); model.thumbnailCameraGO.gameObject.transform.LookAt(po.getThumbnailCameraTarget()); // USE THIS MATRIX TO DRAW THE PO's MESHES SOMEWHERE FAR, FAR AWAY //Debug.Log("RENDER: " + po.Name); Material tmpMat = null; if (po.generator is MaterialTool) { if (po.axMat != null && po.axMat.mat != null) { tmpMat = po.axMat.mat; } else if (po.grouper != null && po.grouper.axMat != null && po.grouper.axMat.mat != null) { tmpMat = po.grouper.axMat.mat; } else { tmpMat = model.axMat.mat; } //Debug.Log("RENDER TEXTURETOOL " + model.thumbnailCameraGO.transform.position + " mesh-> " + model.thumbnailMaterialMesh.vertices.Length + " -- " + tmpMat); Graphics.DrawMesh(model.thumbnailMaterialMesh, model.remoteThumbnailLocation, tmpMat, 0, model.thumbnailCamera); model.thumbnailCamera.Render(); } else { AXParameter op = po.getParameter("Output Mesh"); if (op != null) { // RE-RENDER // After a save or reload, the RenterTextures are empty if (op.meshes != null) { for (int mi = 0; mi < op.meshes.Count; mi++) { AXMesh axmesh = op.meshes [mi]; if (axmesh.mat != null) { tmpMat = axmesh.mat; } else if (po.axMat != null && po.axMat.mat != null) { tmpMat = po.axMat.mat; } else if (po.grouper != null && po.grouper.axMat != null && po.grouper.axMat.mat != null) { tmpMat = po.grouper.axMat.mat; } else { tmpMat = model.axMat.mat; } Graphics.DrawMesh(axmesh.drawMesh, (model.remoteThumbnailLocation * axmesh.transMatrix), tmpMat, 0, model.thumbnailCamera); } } model.thumbnailCamera.Render(); } } // write to texture if (makeTexture) { if (po.thumbnail == null) { po.thumbnail = new Texture2D(256, 256); } po.thumbnail.ReadPixels(new Rect(0, 0, po.renTex.width, po.renTex.height), 0, 0); po.thumbnail.Apply(); } if (makeTexture) { RenderTexture.active = null; } // 3. Set helper objects to inactive model.thumbnailLightGO.SetActive(false); model.thumbnailCameraGO.SetActive(false); }
// GENERATE // This is the main function for generating a Shape, Mesh, or any other output that a node may be tasked with generating. // You can do pre processing of Inputs here, but that might best be done in an override of pollControlValuesFromParmeters(). // // Often, you will be creating a list of AXMesh objects. AXMesh has a Mesh, a Matrix4x4 and a Material // to be used when drawing the ouput to the scene before creating GameObjects. Your list of AXMeshes generated // is pased to the model via parametricObject.finishMultiAXMeshAndOutput(). // // When generate() is called by AX, it will be either with makeGameObjects set to true or false. // makeGameObjects=False is passed when the user is dragging a parameter and the model is regenerateing multiple times per second. // makeGameObjects=True is passed when the user has stopped editing (for example, OnMouseup from a Handle) and it is time to // build a GameObject hierarchy. public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (parametricObject == null || !parametricObject.hasInputMeshReady("Input Mesh")) { return(null); } // At this point the amount variable has been set to the FloatValue of its amount parameter. preGenerate(); // AXMeshes are the key product of a Generator3D List <AXMesh> ax_meshes = new List <AXMesh>(); AXParameter inputSrc_p = P_Input.DependsOn; AXParametricObject inputSrc_po = inputSrc_p.parametricObject; Perlin perlin = new Perlin(); perlin.Frequency = .1f; float factor = amount / 100; if (inputSrc_p != null && inputSrc_p.meshes != null) // Is there an input node connected to this node? { //Debug.Log("P_Input.DependsOn.meshes.Count="+P_Input.DependsOn.meshes.Count + ", "+ P_Input.DependsOn.meshes[0].GetType()); AXMesh amesh = null; for (int i = 0; i < P_Input.DependsOn.meshes.Count; i++) { if (amount == 0) { amesh = P_Input.DependsOn.meshes [i]; } else { // Instance does not inhereit and build on the transform of its source object. amesh = P_Input.DependsOn.meshes [i].Clone(); Mesh m = amesh.mesh; Vector3[] verts = m.vertices; for (int j = 0; j < verts.Length; j++) { //Debug.Log(verts[j] + " " + perlin.GetValue(verts[j])); // float pval = factor * 100 *(float) perlin.GetValue(verts[j]); // float new_x = verts [j].x + pval; // float new_y = verts [j].y + pval; // float new_z = verts [j].z + pval; Vector3 vert = new Vector3(verts[j].x, verts[j].y, verts[j].z); vert = P_Input.DependsOn.meshes[i].drawMeshMatrix.MultiplyPoint3x4(vert); //float len = Mathf.Sqrt(verts[j].x*verts[j].x + verts[j].z*verts[j].z); float len = Mathf.Sqrt(vert.x * vert.x + vert.z * vert.z); float new_x = vert.x; //+ pval; //float new_y = verts[j].y - factor*len*len*verts[j].y/5; //float new_y = vert.y - factor*len*len + pval; float new_y = vert.y - factor * len * len; // * vert.y/5;// + pval; float new_z = vert.z; //+ pval; //Debug.Log(pval + " :::: " + verts[j].x + " :: " + verts[j].z + " + " + Mathf.PerlinNoise (verts[j].x, verts[j].z)); verts [j] = new Vector3(new_x, new_y, new_z); verts [j] = P_Input.DependsOn.meshes[i].drawMeshMatrix.inverse.MultiplyPoint3x4(verts[j]); } m.vertices = verts; } ax_meshes.Add(amesh); } parametricObject.bounds = inputSrc_po.bounds; parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); AXParameter p = parametricObject.getParameter("Amount"); p.initiateRipple_setFloatValueFromGUIChange(5); if (makeGameObjects) { return(parametricObject.makeGameObjectsFromAXMeshes(ax_meshes)); } } return(null); }
// GENERATE PLAN_REPEATER public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool renderToOutputParameter) { if (parametricObject == null || !parametricObject.isActive) { return(null); } //Debug.Log("yo ******* makeGameObjects="+makeGameObjects); // RESULTING MESHES ax_meshes = new List <AXMesh>(); paths_SubsplineIndices = new List <SubsplineIndices[]>(); preGenerate(); planSrc_p = P_Plan.DependsOn; // getUpstreamSourceParameter(P_Plan); planSrc_po = (planSrc_p != null) ? planSrc_p.parametricObject : null; //Debug.Log("planSrc_po = " + planSrc_po.Name+"."+planSrc_p.Name + " ... " + planSrc_p.DependsOn.PType + " ..... " + planSrc_p.getPaths()); P_Plan.polyTree = null; AXShape.thickenAndOffset(ref P_Plan, planSrc_p); if (P_Plan.reverse) { P_Plan.doReverse(); } planPaths = P_Plan.getPaths(); if (planPaths == null || planPaths.Count == 0) { return(null); } // ** CREATE PLAN_SPLINES ** if (planPaths != null && planPaths.Count > 0) { planSplines = new Spline[planPaths.Count]; if (planSplines != null) { for (int i = 0; i < planSplines.Length; i++) { planSplines[i] = new Spline(planPaths[i], (P_Plan.shapeState == ShapeState.Closed) ? true : false); } } } //Debug.Log("controlVertices="+ planSplines[0].controlVertices.Count); // CORNER_MESH GameObject cornerPlugGO = null; if (cornerSrc_p != null) { cornerSrc_po = cornerSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { cornerPlugGO = cornerSrc_po.generator.generate(true, initiator_po, renderToOutputParameter); } } // NODE_MESH GameObject nodePlugGO = null; if (nodeSrc_p != null) { nodeSrc_po = nodeSrc_p.parametricObject; //Debug.Log("yo makeGameObjects="+makeGameObjects+", parametricObject.combineMeshes="+parametricObject.combineMeshes); if (makeGameObjects && !parametricObject.combineMeshes) { nodePlugGO = nodeSrc_po.generator.generate(true, initiator_po, renderToOutputParameter); } } // CELL_MESH GameObject cellPlugGO = null; if (cellSrc_p != null) { cellSrc_po = cellSrc_p.parametricObject; if (makeGameObjects && !parametricObject.combineMeshes) { cellPlugGO = cellSrc_po.generator.generate(true, initiator_po, renderToOutputParameter); } } // Plan // This is the main spline used for the iteration //AXParameter plan_p = ip.DependsOn; // The section spline is used to provide the connective tissue around corners // SECTION // The plan may have multiple paths. Each may generate a separate GO. sectionSrc_p = P_Section.DependsOn; //getUpstreamSourceParameter(P_Section); sectionSrc_po = (sectionSrc_p != null) ? sectionSrc_p.parametricObject : null; if (sectionSrc_po != null) { P_Section.polyTree = null; AXShape.thickenAndOffset(ref P_Section, sectionSrc_p); if (P_Section.reverse) { P_Section.doReverse(); } } float bay_U = parametricObject.floatValue("bay_U"); float bay_V = parametricObject.floatValue("bay_V"); if (bay_U == 0) { bay_U = .1f; } if (bay_V == 0) { bay_V = 10f; } float margin_U = parametricObject.floatValue("margin_U"); Vector2 prevV = new Vector2(); //Vector3 scaler1 = Vector3.one; //float margin = 2.5f; Vector2 firstPM = new Vector2(); Vector2 prevVM = new Vector2(); AXSpline secSpline = null; AXSplineExtrudeGenerator tmpEXSP = null; if (sectionSrc_p != null && sectionSrc_p.spline != null && sectionSrc_p.spline.vertCount > 0) { secSpline = sectionSrc_p.spline; } tmpEXSP = new AXSplineExtrudeGenerator(); Material tmp_mat = parametricObject.axMat.mat; if (parametricObject.axTex != null) { tmpEXSP.uScale = parametricObject.axTex.scale.x; tmpEXSP.vScale = parametricObject.axTex.scale.y; tmpEXSP.uShift = -parametricObject.axTex.shift.x; tmpEXSP.vShift = parametricObject.axTex.shift.y; } float runningU = 0; //ip.spline.getAnglesArray(); //Spline sectionSpline = null; // = new Spline(sectionPath, sectionIsClosed, sec_p.breakGeom, sec_p.breakNorm); GameObject go = null; GameObject planGO = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } // BOUNDING List <AXMesh> boundingMeshes = new List <AXMesh>(); // FOR EACH PATH for (int path_i = 0; path_i < planPaths.Count; path_i++) { if (makeGameObjects && !parametricObject.combineMeshes) { planGO = ArchimatixUtils.createAXGameObject(parametricObject.Name + "_" + path_i, parametricObject); } // **** PREPARE EACH SPLINE *** // Spline planSpline = planSplines[path_i]; planSpline.breakAngleCorners = cornerBreakAngle; planSpline.shapeState = P_Plan.shapeState; // Create subsplines between each break point planSpline.getSmoothSubsplineIndicies(0, maxSegmentLength); // ....... DEBUG //Pather.printPaths(planPaths); planSpline.groupNearBreakAngleVertices(inset * 2); if (planSpline.groupedCornerNodes == null || planSpline.groupedCornerNodes.Count == 0) { inset = 0; } // **** PREPARE EACH SPLINE *** // Matrix4x4 localPlacement_mx = Matrix4x4.identity; // INSET PLANSWEEPS GameObject plansweepGO = null; if (sectionSrc_p != null && inset > 0 && planSpline.insetSplines != null) { // convert planSpline.insetSplines to Paths Paths insetPaths = AXGeometryTools.Utilities.Splines2Paths(planSpline.insetSplines); AXParameter tmpPlanP = new AXParameter(); tmpPlanP.parametricObject = parametricObject; tmpPlanP.paths = insetPaths; tmpPlanP.Type = AXParameter.DataType.Shape; tmpPlanP.shapeState = ShapeState.Open; tmpPlanP.breakGeom = 0; if (planSpline.insetSplines.Count == 1) { tmpPlanP.shapeState = planSpline.insetSplines[0].shapeState; } topCap = false; botCap = false; plansweepGO = generateFirstPass(initiator_po, makeGameObjects, tmpPlanP, P_Section, Matrix4x4.identity, renderToOutputParameter, false); if (makeGameObjects && !parametricObject.combineMeshes && plansweepGO != null) { plansweepGO.transform.parent = go.transform; } } AXMesh tmpMesh = null; if (planSpline.insetSpanSplines != null && planSpline.insetSpanSplines.Count > 0) { //Debug.Log(".....????>> spanSpline.subsplines.Count="+ planSpline.insetSpanSplines.Count + " --- " + planSpline.subsplines.Count ); for (int si = 0; si < planSpline.insetSpanSplines.Count; si++) { planSpline.insetSpanSplines[si].setRepeaterTransforms(si, inset, bay); } // SPAN NODES - MESHES ALONG SUBSPLINES if (nodeSrc_p != null && nodeSrc_p.meshes != null) { //int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ? planSpline.subsplines.Count-1 : planSpline.subsplines.Count; int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ? planSpline.insetSpanSplines.Count - 1 : planSpline.insetSpanSplines.Count; for (int i = 0; i < endCount; i++) { //SubsplineIndices rsi = planSpline.subsplines[i]; Spline spanSpline = planSpline.insetSpanSplines[i]; //Debug.Log(i + "||||||||||> " + spanSpline.toString()); List <Matrix4x4> nodeMatrices = spanSpline.repeaterNodeTransforms; // on each of these nodes, place a nodePlug instance. bool spanNodesAtBreakCorners = true; int starter = (inset > 0 || spanNodesAtBreakCorners) ? 0 : 1; //Debug.Log("starter="+starter); int ender = (inset > 0 || spanSpline.shapeState == ShapeState.Open || planSpline.subsplines.Count == 1) ? nodeMatrices.Count : nodeMatrices.Count - 1; //Debug.Log("starter="+starter +", ender="+ender + ", nodeMatrices.Count=" + nodeMatrices.Count); //Debug.Log("(inset > 0 && spanNodesAtBreakCorners)="+(inset > 0 && spanNodesAtBreakCorners)+", nodeMatrices.Length="+nodeMatrices.Length+", starter="+starter+", ender="+ender); string this_address = ""; if (nodeMatrices != null) { for (int ii = starter; ii < ender; ii++) { this_address = "node_" + path_i + "_" + i + "_" + ii; //Debug.Log("this_address="+this_address); // LOCAL_PLACEMENT localPlacement_mx = localMatrixFromAddress(RepeaterItem.Node, path_i, i, ii); // AX_MESHES for (int mi = 0; mi < nodeSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = nodeSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING boundingMeshes.Add(new AXMesh(nodeSrc_po.boundsMesh, localPlacement_mx * nodeSrc_po.generator.localMatrix)); //Debug.Log("boundingMeshes: " + boundingMeshes.Count); // GAME_OBJECTS if (nodePlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(nodePlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); Vector3 newJitterScale = jitterScale + Vector3.one; copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z); copyGO.transform.localScale += jitterScale; AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; //Debug.Log("ADD ADDRESS: " + this_address); } copyGO.name = copyGO.name + "_" + this_address; //Debug.Log("copyGO.name = "+copyGO.name); copyGO.transform.parent = planGO.transform; } } } } } // \NODE MESHES // CELL NODES - MESHES ALONG SUBSPLINES if (cellSrc_p != null && cellSrc_p.meshes != null) { //int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ? planSpline.subsplines.Count-1 : planSpline.subsplines.Count; int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ? planSpline.insetSpanSplines.Count - 1 : planSpline.insetSpanSplines.Count; for (int i = 0; i < endCount; i++) { //SubsplineIndices rsi = planSpline.subsplines[i]; Spline spanSpline = planSpline.insetSpanSplines[i]; spanSpline.setRepeaterTransforms(i, inset, bay); List <Matrix4x4> cellMatrices = spanSpline.repeaterCellTransforms; // on each of these cell, place a nodePlug instance. //bool spanNodesAtBreakCorners = true; int starter = 0; //spanNodesAtBreakCorners ? 0 : 1; //int ender = (inset > 0 || spanNodesAtBreakCorners) ? cellMatrices.Count : cellMatrices.Count-1; int ender = cellMatrices.Count; //Debug.Log("(inset > 0 && spanNodesAtBreakCorners)="+(inset > 0 && spanNodesAtBreakCorners)+", nodeMatrices.Length="+nodeMatrices.Length+", starter="+starter+", ender="+ender); string this_address = ""; if (cellMatrices != null) { for (int ii = starter; ii < ender; ii++) { // ADDRESS this_address = "cell_" + path_i + "_" + i + "_" + ii; // LOCAL_PLACEMENT localPlacement_mx = localMatrixFromAddress(RepeaterItem.Cell, path_i, i, ii); // AX_MESHES for (int mi = 0; mi < cellSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = cellSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING boundingMeshes.Add(new AXMesh(cellSrc_po.boundsMesh, localPlacement_mx * cellSrc_po.generator.localMatrix)); // GAME_OBJECTS if (cellPlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * cellSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(cellPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); Vector3 newJitterScale = jitterScale + Vector3.one; copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z); copyGO.transform.localScale += jitterScale; AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; //Debug.Log("ADD ADDRESS: " + this_address); } copyGO.name = copyGO.name + "_"; // + this_address; //Debug.Log("copyGO.name = "+copyGO.name); copyGO.transform.parent = planGO.transform; } } } } } // \CELL MESHES } // \each spanSpline // BREAK CORNER MESHES if (cornerSrc_p != null && cornerSrc_p.meshes != null) { for (int bi = 0; bi < planSpline.breakIndices.Count; bi++) { // ADDRESS string this_address = "corner_" + path_i + "_" + planSpline.breakIndices[bi]; // LOCAL_PLACEMENT localPlacement_mx = localMatrixFromAddress(RepeaterItem.Corner, path_i, planSpline.breakIndices[bi]); // AX_MESHES for (int mi = 0; mi < cornerSrc_p.meshes.Count; mi++) { AXMesh dep_amesh = cornerSrc_p.meshes [mi]; tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix); tmpMesh.subItemAddress = this_address; ax_meshes.Add(tmpMesh); } // BOUNDING boundingMeshes.Add(new AXMesh(cornerSrc_po.boundsMesh, localPlacement_mx * cornerSrc_po.generator.localMatrix)); // GAME_OBJECTS if (cornerPlugGO != null && makeGameObjects && !parametricObject.combineMeshes) { Matrix4x4 mx = localPlacement_mx * cornerSrc_po.generator.localMatrixWithAxisRotationAndAlignment; GameObject copyGO = (GameObject)GameObject.Instantiate(cornerPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx)); Vector3 newJitterScale = jitterScale + Vector3.one; copyGO.transform.localScale = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z); copyGO.transform.localScale += jitterScale; AXGameObject axgo = copyGO.GetComponent <AXGameObject>(); if (axgo != null) { axgo.consumerAddress = this_address; } copyGO.name = copyGO.name + "_" + this_address; copyGO.transform.parent = planGO.transform; } } } /* * int cells = Mathf.CeilToInt( md/bay_U ); * int nby = Mathf.CeilToInt( height/bay_V ); * * //Debug.Log ("d="+d+", md="+md); * * float actual_bayx = md/cells; * float actual_bayy = height/nby; * * // CREATE VERSIONS OF INPUT BAY_CENTER MESH(ES) USING BOUNDING BOX * // ****************************************************************************** * // someting similar shoud be added to griditerator, stepiterator, and where else? * * // instead of prev, would be better to create a dictionary of bounds and AXMeshes? * if (bay_span_p != null && (prevActuralBayx != actual_bayx || prevActuralBayx != actual_bayy)) * { * // regnerate the input meshes using actual_bayx * bay_span_p.Parent.setParameterValueByName("uScale", parametricObject.floatValue("uScale")); * bay_span_p.Parent.setParameterValueByName("vScale", parametricObject.floatValue("vScale")); * bay_span_p.Parent.setParameterValueByName("uShift", parametricObject.floatValue("uShift")); * bay_span_p.Parent.setParameterValueByName("vShift", parametricObject.floatValue("vShift")); * * //bay_span_p.Parent.generateOutputNow (makeGameObjects, parametricObject, true);//, new Vector3(actual_bayx, actual_bayy, margin_th)); * * } * // ****************************************************************************** * * * // CREATE VERSIONS OF INPUT BAY_CENTER MESH(ES) USING BOUNDING BOX * // ****************************************************************************** * // someting similar shoud be added to griditerator, stepiterator, and where else? * * // instead of prev, would be better to create a dictionary of bounds and AXMeshes? * if (node_p != null && (prevActuralBayx != actual_bayx || prevActuralBayx != actual_bayy)) * { * // regnerate the input meshes using actual_bayx * node_p.Parent.setParameterValueByName("uScale", parametricObject.floatValue("uScale")); * node_p.Parent.setParameterValueByName("vScale", parametricObject.floatValue("vScale")); * node_p.Parent.setParameterValueByName("uShift", parametricObject.floatValue("uShift")); * node_p.Parent.setParameterValueByName("vShift", parametricObject.floatValue("vShift")); * * //node_p.Parent.generateOutputNow (makeGameObjects, parametricObject, true);//, new Vector3(actual_bayx, actual_bayy, margin_th)); * * } * // ****************************************************************************** */ //margin_U = .5f; if (margin_U > 0 && planSpline.isClosed) { AXSpline connSpline2 = new AXSpline(); connSpline2.Push(prevVM); connSpline2.Push(prevV); connSpline2.Push(firstPM); connSpline2.isClosed = false; tmpEXSP.uShift = parametricObject.floatValue("uShift") + (runningU) / tmpEXSP.uScale; Mesh mesh = tmpEXSP.generate(connSpline2, secSpline); ax_meshes.Add(new AXMesh(mesh, Matrix4x4.identity, tmp_mat)); } if (makeGameObjects && !parametricObject.combineMeshes) { planGO.transform.parent = go.transform; } } // end paths //GameObject.DestroyImmediate(bay_spanPlugGO); GameObject.DestroyImmediate(cornerPlugGO); GameObject.DestroyImmediate(nodePlugGO); GameObject.DestroyImmediate(cellPlugGO); // FINISH AX_MESHES //Debug.Log("finish " + ax_meshes.Count); parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter); // 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); // FINISH GAME_OBJECTS if (makeGameObjects) { if (parametricObject.combineMeshes) { go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true); } Matrix4x4 tmx = parametricObject.getLocalMatrix(); go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); go.transform.position = AXUtilities.GetPosition(tmx); go.transform.localScale = parametricObject.getLocalScaleAxisRotated(); //AXUtilities.GetScale(tmx); if (P_Plan.reverse) { P_Plan.doReverse(); } if (P_Section != null && P_Section.reverse) { P_Section.doReverse(); } return(go); } else { // Submit AXMeshes for realtime rendering //parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter); //setBoundaryFromMeshes(ax_meshes); } if (P_Plan.reverse) { P_Plan.doReverse(); } if (P_Section != null && P_Section.reverse) { P_Section.doReverse(); } return(null); }
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.mostRecentlyInstantiatedPO; if (mostRecentPO == null) { 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 "Channeler": AXParameter inputer = po.getOrAddInputMesh(); inputer.makeDependentOn(editor.OutputParameterBeingDragged); 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 "ShapeChanneler": foreach (AXParametricObject selpo in selectedPOs) { AXParameter inputer = po.addInputSpline(); inputer.makeDependentOn(selpo.generator.P_Output); po.generator.P_Output.shapeState = inputer.shapeState; } Rect sr = AXUtilities.getBoundaryRectFromPOs(selectedPOs); po.rect.x = sr.center.x - po.rect.width / 2; po.rect.y = sr.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; model.mostRecentlyInstantiatedPO = po; //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(); * */ }
// SHAPE_OFFSETTER :: GENERATE public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (P_Input == null || inputSrc_p == null) { return(null); } // PRE_GENERATE preGenerate(); P_Input.polyTree = null; AXShape.thickenAndOffset(ref P_Input, inputSrc_p); //if (P_Input.polyTree != null) //Debug.Log(" P_Input.polyTree 1="+ Clipper.PolyTreeToPaths(P_Input.polyTree).Count); //base.generate(ref visited, initiator_po, isReplica); if (P_Output == null) { return(null); } if (thickness > 0) { P_Output.thickness = thickness; P_Output.endType = AXClipperLib.EndType.etClosedLine; } else { P_Output.endType = AXClipperLib.EndType.etClosedPolygon; } if (P_Output.shapeState == ShapeState.Closed) { // CLOSED P_Output.offset = offset; //P_Output.roundness = roundness; } else { // OPEN switch (P_Output.openEndType) { case AXParameter.OpenEndType.Butt: P_Output.endType = AXClipperLib.EndType.etOpenButt; break; case AXParameter.OpenEndType.Square: P_Output.endType = AXClipperLib.EndType.etOpenSquare; break; case AXParameter.OpenEndType.Round: P_Output.endType = AXClipperLib.EndType.etOpenRound; break; default: P_Output.endType = AXClipperLib.EndType.etOpenSquare; break; } } P_Output.polyTree = null; AXShape.thickenAndOffset(ref P_Output, P_Input); //if (P_Output.polyTree != null) //Debug.Log(" P_Output.polyTree 1="+ Clipper.PolyTreeToPaths(P_Output.polyTree).Count); if (P_Output.polyTree != null) { transformPolyTree(P_Output.polyTree, localMatrix); } else if (P_Output.paths != null) { P_Output.paths = transformPaths(P_Output.paths, localMatrix); P_Output.transformedControlPaths = P_Output.paths; } //Debug.Log("stats"); AX.Generators.Generator2D.deriveStatsETC(P_Output); //P_Output.transformedControlPaths = transformPaths(P_Output.controlPaths, localMatrix); //output.getTransformedControlPaths(); //P_Output.paths = transformPaths(P_Output.controlPaths, localMatrix); // output.getTransformedControlPaths(); // may be altered before generate is over... //Debug.Log(" P_Output.path="+ P_Output.paths); //Debug.Log(" P_Output.transformedControlPaths="+ P_Output.transformedControlPaths); //if (P_Output.polyTree != null) //Debug.Log(" P_Output.polyTree 2="+ Clipper.PolyTreeToPaths(P_Output.polyTree).Count); calculateBounds(); return(null); }
// GENERATE BOX public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool renderToOutputParameter) { if (parametricObject == null || !parametricObject.isActive) { return(null); } preGenerate(); AXPlaneGenerator e = new AXPlaneGenerator(); e.side_x = sizeX; e.side_y = sizeY; e.side_z = sizeZ; e.top = top; e.bottom = bottom; Mesh mesh = new Mesh(); e.generate(ref mesh, parametricObject.axTex); mesh.RecalculateBounds(); //AXGeometryTools.Utilities.calculateMeshTangents(ref mesh); AXMesh tmpAXmesh; tmpAXmesh = new AXMesh(mesh, Matrix4x4.identity, parametricObject.axMat.mat); tmpAXmesh.name = parametricObject.Name; tmpAXmesh.hasContinuousUV = parametricObject.boolValue("hasContinuousUV"); tmpAXmesh.makerPO = parametricObject; List <AXMesh> ax_meshes = new List <AXMesh>(); ax_meshes.Add(tmpAXmesh); //parametricObject.finishSingleAXMeshAndOutput(tmpAXmesh, isReplica); parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter); setBoundaryFromAXMeshes(ax_meshes); if (makeGameObjects) { GameObject go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, false); //Matrix4x4 tmx = parametricObject.getLocalMatrix(); //go.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); //go.transform.position = AXUtilities.GetPosition(tmx); //go.transform.localScale = parametricObject.getLocalScale(); return(go); } //Debug.Log ("gen time="+sw.stop ()); return(null); }
public static string allSelectedPOsAndInputsAsJson(AXModel m) { Debug.Log("allSelectedPOsAndInputsAsJson"); /* We don't know if some of the supart PO's are already selected * so maintain a registry and exclude double entries into the json * */ List <string> registry = new List <string>(); // gather relations as you go... List <AXRelation> rels = new List <AXRelation>(); StringBuilder sb = new StringBuilder(); sb.Append("{"); Debug.Log("ASIGN:: model_guid=" + m.Guid); sb.Append("\"model_guid\": \"" + m.Guid + "\""); // ALL PARAMETRIC_OBJECTS IN THIS TREE sb.Append(", \"parametric_objects\": ["); // begin parametric_objects for (int i = 0; i < m.selectedPOs.Count; i++) { AXParametricObject po = m.selectedPOs[i]; if (!registry.Contains(po.Guid)) { sb.Append(((i > 0)?",":"") + JSONSerializersAX.ParametricObjectAsJSON(po)); registry.Add(po.Guid); } foreach (AXParameter p in po.parameters) { foreach (AXRelation rr in p.relations) { if (!rels.Contains(rr)) { rels.Add(rr); } } } // SUB_NODES po.gatherSubnodes(); foreach (AXParametricObject spo in po.subnodes) { if (registry.Contains(spo.Guid)) // don't copy subparts that were selected and already added { continue; } sb.Append(',' + JSONSerializersAX.ParametricObjectAsJSON(spo)); registry.Add(spo.Guid); foreach (AXParameter p in spo.parameters) { foreach (AXRelation rr in p.relations) { if (!rels.Contains(rr)) { rels.Add(rr); } } } } } sb.Append("]"); // end parametric_objects // add relations to json string thecomma; // RELATIONS if (m.relations != null && m.relations.Count > 0) { sb.Append(", \"relations\": ["); // begin parametric_objects thecomma = ""; foreach (AXRelation rr in m.relations) { sb.Append(thecomma + rr.asJSON()); thecomma = ", "; } } sb.Append("]"); sb.Append("}"); // end collection return(sb.ToString()); }
public static AXParametricObject addNodeToCurrentModel(string nodeName, bool panTo = true, AXParametricObject basedOnPO = null) { AXModel model = getOrMakeSelectedModel(); Undo.RegisterCompleteObjectUndo(model, "Add Generator named " + nodeName); AXParametricObject npo = model.createNode(nodeName, panTo, basedOnPO); if (npo == null) { return(null); } if (basedOnPO != null) { //Debug.Log("basedOnPO.Name="+basedOnPO.Name); basedOnPO.copyTransformTo(npo); } ArchimatixEngine.repaintGraphEditorIfExistsAndOpen(); bool isInstanceofCurrentGrouper = ((npo.generator is IReplica) && model.currentWorkingGroupPO != null && basedOnPO == model.currentWorkingGroupPO); if (model.currentWorkingGroupPO != null) { List <AXParametricObject> npos = new List <AXParametricObject>(); npos.Add(npo); if (!isInstanceofCurrentGrouper) { model.currentWorkingGroupPO.addGroupees(npos); } } if (isInstanceofCurrentGrouper) { model.currentWorkingGroupPO = model.currentWorkingGroupPO.grouper; } return(npo); }
// JSON SERIALIZATION public static string ParametricObjectAsJSON(AXParametricObject po) { StringBuilder sb = new StringBuilder(); sb.Append("{"); sb.Append(" \"basedOnAssetWithGUID\":\"" + po.basedOnAssetWithGUID + "\""); sb.Append(",\"author\":\"" + po.author + "\""); sb.Append(",\"tags\":\"" + po.tags + "\""); sb.Append(",\"guid\":\"" + po.Guid + "\""); sb.Append(", \"name\":\"" + po.Name + "\""); sb.Append(", \"description\":\"" + po.description + "\""); sb.Append(", \"type\":\"" + po.Type + "\""); sb.Append(", \"isInitialized\":\"" + po.isInitialized + "\""); sb.Append(", \"documentationURL\":\"" + po.documentationURL + "\""); sb.Append(", \"includeInSidebarMenu\":\"" + po.includeInSidebarMenu + "\""); sb.Append(",\"grouperKey\":\"" + po.grouperKey + "\""); sb.Append(", \"rect\":" + AXJson.RectToJSON(po.rect)); sb.Append(", \"bounds\":" + AXJson.BoundsToJSON(po.bounds)); sb.Append(", \"transMatrix\":" + AXJson.Matrix4x4ToJSON(po.transMatrix)); if (po.curve != null && po.curve.Count > 0) { sb.Append(", \"curve\":" + AXJson.CurveToJson(po.curve)); } sb.Append(", \"sortval\":\"" + po.sortval + "\""); sb.Append(", \"combineMeshes\":\"" + po.combineMeshes + "\""); sb.Append(", \"isRigidbody\":\"" + po.isRigidbody + "\""); sb.Append(", \"colliderType\":\"" + po.colliderType.GetHashCode() + "\""); sb.Append(", \"axStaticEditorFlags\":\"" + po.axStaticEditorFlags.GetHashCode() + "\""); // material //Debug.Log ("ENCODE MATERIAL::::"); #if UNITY_EDITOR if (po.axMat != null && po.axMat.mat != null) { string matPath = AssetDatabase.GetAssetOrScenePath(po.axMat.mat); if (!String.IsNullOrEmpty(matPath)) { sb.Append(", \"material_assetGUID\":\"" + AssetDatabase.AssetPathToGUID(matPath) + "\""); } } #endif // code if (po.code != null) { sb.Append(", \"code\":\"" + po.code.Replace("\n", ";") + "\""); } // parameters sb.Append(", \"parameters\": ["); // begin parameters string the_comma = ""; foreach (AXParameter p in po.parameters) { sb.Append(the_comma + p.asJSON()); the_comma = ", "; } sb.Append("]"); // end parameters // shapes if (po.shapes != null) { sb.Append(", \"shapes\": ["); // begin parameters the_comma = ""; foreach (AXShape shp in po.shapes) { sb.Append(the_comma + shp.asJSON()); the_comma = ", "; } sb.Append("]"); // end parameters } // handles if (po.handles != null && po.handles.Count > 0) { sb.Append(", \"handles\": ["); // begin parameters the_comma = ""; foreach (AXHandle h in po.handles) { sb.Append(the_comma + h.asJSON()); the_comma = ", "; } sb.Append("]"); } // end parameters // cameraSettings if (po.cameraSettings != null) { sb.Append(",\"cameraSettings\":" + JSONSerializersAX.AXCameraAsJSON(po.cameraSettings)); } // finish sb.Append("}"); // end parametri_object //Debug.Log (sb.ToString()); return(sb.ToString()); }
public static void DrawOutputPaths(Texture2D canvas, AXParametricObject po, float texSize, float imageSize) { if (po == null) { return; } // GET OUTPUT PARAMETER AXParameter p = po.getPreferredOutputSplineParameter(); if (p == null) { return; } bool isClosed = (p.shapeState == ShapeState.Closed); Paths paths = null; if (p.polyTree != null) { paths = Clipper.PolyTreeToPaths(p.polyTree); } else if (p.paths != null) { paths = p.paths; } Rect bounds = AXGeometryTools.Utilities.getClipperBounds(paths); float maxdim = (bounds.width > bounds.height) ? bounds.width : bounds.height; float scale = imageSize / maxdim; long[] shifter = AXGeometryTools.Utilities.getShifterToPathsCenter(paths); Paths centeredPaths = AXGeometryTools.Utilities.shiftPathsAsGroup(paths, shifter); //Archimatix.printPaths(centeredPaths); Vector2 offset = new Vector2(texSize / 2, texSize / 2); float rot = po.floatValue("Rot_Z"); Color lineColor = Color.magenta; lineColor = new Color(1, .5f, 1); foreach (Path path in centeredPaths) { Library.DrawPathsOnTexture(canvas, AXGeometryTools.Utilities.path2Vec2s(path, rot, scale), offset, isClosed, lineColor); } // AXES long s = (shifter[2] / 18); Path xaxis = new Path(); xaxis.Add(new IntPoint(-s - shifter[0], -shifter[1])); xaxis.Add(new IntPoint(s - shifter[0], -shifter[1])); Library.DrawPathsOnTexture(canvas, AXGeometryTools.Utilities.path2Vec2s(xaxis, rot, scale), offset, false, Color.white); Path yaxis = new Path(); yaxis.Add(new IntPoint(-shifter[0], -s - shifter[1])); yaxis.Add(new IntPoint(-shifter[0], s - shifter[1])); Library.DrawPathsOnTexture(canvas, AXGeometryTools.Utilities.path2Vec2s(yaxis, rot, scale), offset, false, Color.white); }
public static AXParametricObject ParametricObjectFromJSON(AX.SimpleJSON.JSONNode jn) { AXParametricObject po = new AXParametricObject(jn["type"], jn["name"]); po.Guid = jn["guid"].Value; po.basedOnAssetWithGUID = jn["basedOnAssetWithGUID"].Value; po.description = jn["description"].Value; po.author = jn["author"].Value; po.tags = jn["tags"].Value; po.documentationURL = jn["documentationURL"].Value; if (jn["includeInSidebarMenu"] != null) { po.includeInSidebarMenu = jn["includeInSidebarMenu"].AsBool; } else { po.includeInSidebarMenu = true; } po.isInitialized = jn["isInitialized"].AsBool; po.grouperKey = jn["grouperKey"].Value; if (jn["sortval"] != null) { po.sortval = jn["sortval"].AsFloat; } po.curve = AXJson.CurveFromJSON(jn["curve"]); po.rect = AXJson.RectFromJSON(jn["rect"]); po.bounds = AXJson.BoundsFromJSON(jn["bounds"]); po.transMatrix = AXJson.Matrix4x4FromJSON(jn["transMatrix"]); po.combineMeshes = jn["combineMeshes"].AsBool; po.isRigidbody = jn["isRigidbody"].AsBool; po.colliderType = (AXGeometryTools.ColliderType)jn["colliderType"].AsInt; po.axStaticEditorFlags = (AXStaticEditorFlags)jn["axStaticEditorFlags"].AsInt; //Debug.Log(po.Name + " " + po.grouperKey); // material // look to see if there is a material matching this name.... #if UNITY_EDITOR if (jn["material_assetGUID"] != null) { string path = AssetDatabase.GUIDToAssetPath(jn["material_assetGUID"].Value); //Debug.Log("AssetDatabase.GUIDToAssetPath("+jn["material_assetGUID"].Value+") has path: " + path); // REDO if (path != null) { //Debug.Log(jn["Name"] + ": path="+path); Material matter = (Material)AssetDatabase.LoadAssetAtPath(path, typeof(Material)); //Debug.Log("..."+matter); //po.axMat.mat = (Material) AssetDatabase.LoadAssetAtPath(path, typeof(Material)) ; if (po.axMat == null) { po.axMat = new AXMaterial(); } po.axMat.mat = matter; } } #endif // code if (jn["code"] != null) { po.code = jn["code"].Value.Replace(";", "\n"); } // parameters if (jn["parameters"] != null) { po.parameters = new List <AXParameter>(); foreach (AX.SimpleJSON.JSONNode jn_p in jn["parameters"].AsArray) { po.addParameter(AXParameter.fromJSON(jn_p)); } } // shapes if (jn["shapes"] != null) { po.shapes = new List <AXShape>(); foreach (AX.SimpleJSON.JSONNode jn_p in jn["shapes"].AsArray) { po.shapes.Add(AXShape.fromJSON(po, jn_p)); } } // handles if (jn["handles"] != null) { po.handles = new List <AXHandle>(); foreach (AX.SimpleJSON.JSONNode jn_h in jn["handles"].AsArray) { po.handles.Add(AXHandle.fromJSON(jn_h)); } } // cameraSettings if (jn["cameraSettings"] != null) { po.cameraSettings = JSONSerializersAX.AXCameraFromJSON(jn["cameraSettings"]); po.cameraSettings.setPosition(); } // make the generator for this po po.instantiateGenerator(); return(po); }
public static AXParametricObject pasteParametricObjectFromString(String json_string) { if (string.IsNullOrEmpty(json_string)) { json_string = EditorGUIUtility.systemCopyBuffer; } if (string.IsNullOrEmpty(json_string)) { return(null); } AXModel model = null; // 1. First choice is to use a selected model.... if (ArchimatixEngine.currentModel != null) { model = ArchimatixEngine.currentModel; } bool doInstantiation = true; if (model == null) { // ok, are there other models in the scene that the user doesn't realize arene't selected? AXModel[] axModels = GameObject.FindObjectsOfType(typeof(AXModel)) as AXModel[]; if (axModels != null) { if (axModels.Length == 1) { // Offer this model as a button, but also give opportunity to create a new one... int option = EditorUtility.DisplayDialogComplex("Instantiating Library Item", "There is no AX model currently selected", "Cancel", "Add to " + axModels[0], "Create a new Model"); switch (option) { // Save Scene case 0: doInstantiation = false; break; // Save and Quit. case 1: model = axModels[0]; break; case 2: GameObject axgo = AXEditorUtilities.createNewModel(); model = axgo.GetComponent <AXModel>(); doInstantiation = false; break; default: doInstantiation = false; break; } } else if (axModels.Length > 1) { // Throw up a dialog to see if use wants to go select one of the existing models or create a new one. if (EditorUtility.DisplayDialog("Instantiating Library Item", "There is no AX model currently selected", "Select and Existing Model", "Create a new Model")) { return(null); } } } } if (!doInstantiation) { return(null); } if (model == null) { // Well, then, we tried everything.... GameObject axgo = AXEditorUtilities.createNewModel(); model = axgo.GetComponent <AXModel>(); } List <AXParametricObject> poList = new List <AXParametricObject>(); List <AXRelation> relationList = new List <AXRelation>(); AX.SimpleJSON.JSONNode json = null; try { json = AX.SimpleJSON.JSON.Parse(json_string); } catch { return(null); } if (json == null) { return(null); } if (json["parametric_objects"] != null) { foreach (AX.SimpleJSON.JSONNode poNode in json["parametric_objects"].AsArray) { poList.Add(JSONSerializersAX.ParametricObjectFromJSON(poNode)); } } foreach (AX.SimpleJSON.JSONNode rNode in json["relations"].AsArray) { relationList.Add(AXRelation.fromJSON(rNode)); } //Debug.Log (rNode); // make sure there is a game object ready to instantiate this on if (model == null) { // check if the user really wants to create a new model... GameObject axgo = AXEditorUtilities.createNewModel(); model = axgo.GetComponent <AXModel>(); } Undo.RegisterCompleteObjectUndo(model, "Add Library Object"); AXParametricObject head_po = poList[0]; if (model.currentWorkingGroupPO != null && model.currentWorkingGroupPO.Name != head_po.Name) { head_po.grouperKey = model.currentWorkingGroupPO.Guid; } else { head_po.grouperKey = null; } // ADD AND RIGUP // !!! Actually add the library item (as a list of PO's and Relations) to the model model.addAndRigUp(poList, relationList); head_po.startStowInputs(); //if (poList[0].is2D() && ArchimatixEngine.workingAxis != (int) Axis.NONE) // poList[0].intValue ("Axis", ArchimatixEngine.workingAxis); model.setRenderMode(AXModel.RenderMode.GameObjects); model.generate(); ArchimatixEngine.currentModel = model; Selection.activeGameObject = model.gameObject; model.selectOnlyPO(head_po); head_po.focusMe = true; //AXParametricObject mostRecentPO = model.recentlySelectedPO; AXParametricObject mostRecentPO = model.recentlySelectedPO; //getPOSelectedBefore(head_po); //Debug.Log ("model.focusPointInGraphEditor="+model.focusPointInGraphEditor); float pos_x = (model.focusPointInGraphEditor.x) + 100; // + UnityEngine.Random.Range(-100, 300); float pos_y = (model.focusPointInGraphEditor.y - 250) + UnityEngine.Random.Range(-10, 0); if (mostRecentPO != null) { //pos_x = mostRecentPO.rect.x + 200; //pos_y = mostRecentPO.rect.y; } //Debug.Log (new Rect(pos_x, pos_y, 150, 100)); head_po.rect = new Rect(pos_x, pos_y, 150, 500); //Debug.Log ("OK "+po.Name+".focusMe = " + po.focusMe); // make sure it is in view in the editor window.... //model.startPanningToRect(head_po.rect); //model.cleanGraph(); model.autobuild(); head_po.generator.adjustWorldMatrices(); model.selectOnlyPO(head_po); // Paste inside grouper? if (model.currentWorkingGroupPO != null && model.currentWorkingGroupPO.Name != head_po.Name) { model.currentWorkingGroupPO.addGroupee(head_po); } if (model.currentWorkingGroupPO != null && model.currentWorkingGroupPO.Name == head_po.Name) { model.currentWorkingGroupPO = model.currentWorkingGroupPO.grouper; } //model.beginPanningToRect(head_po.rect); //AXNodeGraphEditorWindow.zoomToRectIfOpen(head_po.rect); //Debug.Log(" 1 model.selectedPOs.Count="+model.selectedPOs.Count + " " + model.selectedPOs[0].Name ); // EDITOR WINDOW ArchimatixEngine.repaintGraphEditorIfExistsAndOpen(); // SCENEVIEW if (SceneView.lastActiveSceneView != null) { //Debug.Log("REPAINT"); SceneView.lastActiveSceneView.Repaint(); } //Debug.Log("--> ArchimatixEngine.currentModel=" + ArchimatixEngine.currentModel); return(head_po); }
// COPY OPERATION public static string allSelectedPOsAsJson(AXModel m) { Debug.Log("allSelectedPOsAsJson"); //List<string> registry = new List<string>(); // gather relations as you go... List <AXRelation> rels = new List <AXRelation>(); StringBuilder sb = new StringBuilder(); sb.Append("{"); sb.Append("\"model_guid\": \"" + m.Guid + "\""); sb.Append(", \"parametric_objects\": ["); // begin parametric_objects for (int i = 0; i < m.selectedPOs.Count; i++) { AXParametricObject po = m.selectedPOs[i]; // if this po is an instance, get its source as json to store in the clipboard if (po.Type == "Instance") { AXParametricObject src_po = po.getParameter("Input Mesh").DependsOn.Parent; if (!m.isSelected(src_po)) { po = src_po; } } sb.Append(((i > 0)?",":"") + JSONSerializersAX.ParametricObjectAsJSON(po)); foreach (AXParameter p in po.parameters) { foreach (AXRelation rr in p.relations) { if (!rels.Contains(rr)) { rels.Add(rr); } } } // SUB_NODES if (po.inputsStowed) { // copy them too! po.gatherSubnodes(); foreach (AXParametricObject spo in po.subnodes) { sb.Append(',' + JSONSerializersAX.ParametricObjectAsJSON(spo)); // gather relations foreach (AXParameter p in spo.parameters) { foreach (AXRelation rr in p.relations) { if (!rels.Contains(rr)) { rels.Add(rr); } } } } } } sb.Append("]"); // end parametric_objects // add relations to json string thecomma; // RELATIONS if (m.relations != null && m.relations.Count > 0) { sb.Append(", \"relations\": ["); // begin parametric_objects thecomma = ""; foreach (AXRelation rr in m.relations) { sb.Append(thecomma + rr.asJSON()); thecomma = ", "; } } sb.Append("]"); /* to retrieve later... * if (jn["relations"] != null) * { * foreach(AX.SimpleJSON.JSONNode jn_r in jn["relations"].AsArray) * model.addRelationJSON(jn_r); * } */ sb.Append("}"); // end collection return(sb.ToString()); }
// GENERATE // This is the main function for generating a Shape, Mesh, or any other output that a node may be tasked with generating. // You can do pre processing of Inputs here, but that might best be done in an override of pollControlValuesFromParmeters(). // // Often, you will be creating a list of AXMesh objects. AXMesh has a Mesh, a Matrix4x4 and a Material // to be used when drawing the ouput to the scene before creating GameObjects. Your list of AXMeshes generated // is pased to the model via parametricObject.finishMultiAXMeshAndOutput(). // // When generate() is called by AX, it will be either with makeGameObjects set to true or false. // makeGameObjects=False is passed when the user is dragging a parameter and the model is regenerateing multiple times per second. // makeGameObjects=True is passed when the user has stopped editing (for example, OnMouseup from a Handle) and it is time to // build a GameObject hierarchy. public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (parametricObject == null || !parametricObject.hasInputMeshReady("Input Mesh")) { return(null); } // At this point the amount variable has been set to the FloatValue of its amount parameter. preGenerate(); //Vector3 center = Vector3.zero; // AXMeshes are the key product of a Generator3D List <AXMesh> ax_meshes = new List <AXMesh>(); AXParameter inputSrc_p = P_Input.DependsOn; AXParametricObject inputSrc_po = inputSrc_p.parametricObject; // GameObject go = null; // if (makeGameObjects && ! parametricObject.combineMeshes) // go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); if (makeGameObjects && !parametricObject.combineMeshes) { GameObject GOsToDeformPlug = inputSrc_po.generator.generate(true, initiator_po, isReplica); modifyGameObject(GOsToDeformPlug, Matrix4x4.identity); Matrix4x4 tmx = parametricObject.getLocalMatrix(); GOsToDeformPlug.transform.rotation = AXUtilities.QuaternionFromMatrix(tmx); GOsToDeformPlug.transform.position = AXUtilities.GetPosition(tmx); GOsToDeformPlug.transform.localScale = parametricObject.getLocalScaleAxisRotated(); //AXUtilities.GetScale(tmx); return(GOsToDeformPlug); } else { // COMBINE if (inputSrc_p != null && inputSrc_p.meshes != null) // Is there an input node connected to this node? { //Debug.Log("P_Input.DependsOn.meshes.Count="+P_Input.DependsOn.meshes.Count + ", "+ P_Input.DependsOn.meshes[0].GetType()); AXMesh amesh = null; // EACH MESH for (int i = 0; i < P_Input.DependsOn.meshes.Count; i++) { // Instance does not inhereit and build on the transform of its source object. amesh = P_Input.DependsOn.meshes [i].Clone(); Mesh m = amesh.mesh; Vector3[] verts = m.vertices; // ---------- EACH VERTEX ---------------------- for (int j = 0; j < verts.Length; j++) { Vector3 vert = new Vector3(verts[j].x, verts[j].y, verts[j].z); vert = P_Input.DependsOn.meshes[i].drawMeshMatrix.MultiplyPoint3x4(vert); float scale = 1; if (modifierCurve != null) { scale = modifierCurve.Evaluate(vert.y) * (1 - (amount * vert.y)); } vert = new Vector3(vert.x * scale, vert.y, vert.z * scale); // Vector3 n = -vert.normalized; // n *= scale; // vert = vert + n; verts [j] = P_Input.DependsOn.meshes[i].drawMeshMatrix.inverse.MultiplyPoint3x4(vert); } // ---------- EACH VERTEX ---------------------- m.vertices = verts; //} ax_meshes.Add(amesh); } parametricObject.bounds = inputSrc_po.bounds; parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); if (makeGameObjects) { if (parametricObject.combineMeshes) { return(parametricObject.makeGameObjectsFromAXMeshes(ax_meshes)); } } } } return(null); }
// GENERATE // This is the main function for generating a Shape, Mesh, or any other output that a node may be tasked with generating. // You can do pre processing of Inputs here, but that might best be done in an override of pollControlValuesFromParmeters(). // // Often, you will be creating a list of AXMesh objects. AXMesh has a Mesh, a Matrix4x4 and a Material // to be used when drawing the ouput to the scene before creating GameObjects. Your list of AXMeshes generated // is pased to the model via parametricObject.finishMultiAXMeshAndOutput(). // // When generate() is called by AX, it will be either with makeGameObjects set to true or false. // makeGameObjects=False is passed when the user is dragging a parameter and the model is regenerateing multiple times per second. // makeGameObjects=True is passed when the user has stopped editing (for example, OnMouseup from a Handle) and it is time to // build a GameObject hierarchy. public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { planSrc_p = P_Plan.DependsOn; // getUpstreamSourceParameter(P_Plan); planSrc_po = (planSrc_p != null) ? planSrc_p.parametricObject : null; if (planSrc_p == null) { return(null); } //Debug.Log("planSrc_po = " + planSrc_po.Name+"."+planSrc_p.Name + " ... " + planSrc_p.DependsOn.PType + " ..... " + planSrc_p.getPaths()); P_Plan.polyTree = null; AXShape.thickenAndOffset(ref P_Plan, planSrc_p); if (P_Plan.reverse) { P_Plan.doReverse(); } planPaths = P_Plan.getPaths(); if (planPaths == null || planPaths.Count == 0) { return(null); } // ** CREATE PLAN_SPLINES ** if (planPaths != null && planPaths.Count > 0) { planSplines = new Spline[planPaths.Count]; if (planSplines != null) { for (int i = 0; i < planSplines.Length; i++) { planSplines[i] = new Spline(planPaths[i], (P_Plan.shapeState == ShapeState.Closed) ? true : false); } } } // FOR EACH PATH for (int path_i = 0; path_i < planPaths.Count; path_i++) { Spline planSpline = planSplines[path_i]; planSpline.breakAngleCorners = 35; planSpline.shapeState = P_Plan.shapeState; //Matrix4x4 mm = planSpline.matrixAtLength(4.5f); } if (parametricObject == null || !parametricObject.hasInputMeshReady("Input Mesh")) { return(null); } // At this point the amount variable has been set to the FloatValue of its amount parameter. preGenerate(); //Vector3 center = Vector3.zero; // AXMeshes are the key product of a Generator3D List <AXMesh> ax_meshes = new List <AXMesh>(); AXParameter inputSrc_p = P_Input.DependsOn; AXParametricObject inputSrc_po = inputSrc_p.parametricObject; Spline planSpl = planSplines[0]; if (inputSrc_p != null && inputSrc_p.meshes != null) // Is there an input node connected to this node? { //Debug.Log("P_Input.DependsOn.meshes.Count="+P_Input.DependsOn.meshes.Count + ", "+ P_Input.DependsOn.meshes[0].GetType()); AXMesh amesh = null; // EACH MESH for (int i = 0; i < P_Input.DependsOn.meshes.Count; i++) { // if (amount == 0) // { // amesh = P_Input.DependsOn.meshes [i]; // } // else{ // Instance does not inhereit and build on the transform of its source object. amesh = P_Input.DependsOn.meshes [i].Clone(); Mesh m = amesh.mesh; Vector3[] verts = m.vertices; // ---------- EACH VERTEX ---------------------- for (int j = 0; j < verts.Length; j++) { Vector3 vert = new Vector3(verts[j].x, verts[j].y, verts[j].z); vert = P_Input.DependsOn.meshes[i].drawMeshMatrix.MultiplyPoint3x4(vert); // THE SPLINE POSITION MATRIX Matrix4x4 warperM = planSpl.matrixAtLength(vert.x); // SCALE float scale = modifierCurve.Evaluate(vert.x); // TWIST if (turn != 0 || twist != 0 || scale != 0) { warperM *= Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(vert.x * twist + turn + scale, 0, 0), Vector3.one); } vert = warperM.MultiplyPoint3x4(new Vector3(0, vert.y, vert.z));; verts [j] = P_Input.DependsOn.meshes[i].drawMeshMatrix.inverse.MultiplyPoint3x4(vert); } // ---------- EACH VERTEX ---------------------- m.vertices = verts; //} amesh.mesh.RecalculateNormals(); ax_meshes.Add(amesh); } setBoundaryFromAXMeshes(ax_meshes); //parametricObject.bounds = inputSrc_po.bounds; parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); if (makeGameObjects) { return(parametricObject.makeGameObjectsFromAXMeshes(ax_meshes)); } } return(null); }
} // \OnScenView public override int customNodeGUIZone_4(int cur_y, AXNodeGraphEditorWindow editor, AXParametricObject po, float x = 0, float w = 150) { float cur_x = ArchimatixUtils.cur_x; Rect pRect = new Rect(x, cur_y, w, 16); //float box_w = ArchimatixUtils.paletteRect.width - cur_x - 3*ArchimatixUtils.indent; float box_w = pRect.width - cur_x - 1 * ArchimatixUtils.indent; int lineHgt = (int)pRect.height; //int gap = 5; //int margin = 24; //float wid = pRect.width-margin; // LABEL Rect boxRect = new Rect(cur_x + ArchimatixUtils.indent + 3, cur_y, box_w, pRect.height); Rect lRect = boxRect; lRect.x += 3; lRect.width -= 10; lRect.y = cur_y; GUI.Label(lRect, "Curve Points: " + po.curve.Count); cur_y += 16; GUIStyle labelStyle = new GUIStyle(GUI.skin.GetStyle("Label")); labelStyle.fixedWidth = 150; float origLabelWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 10; for (int i = 0; i < po.curve.Count; i++) { lRect.y = cur_y; GUILayout.BeginArea(lRect); EditorGUILayout.BeginHorizontal(); GUILayout.Label("[" + i + "] ", GUILayout.MaxWidth(15)); EditorGUI.BeginChangeCheck(); po.curve[i].position.x = EditorGUILayout.FloatField("X", po.curve[i].position.x, GUILayout.MinWidth(50)); if (EditorGUI.EndChangeCheck()) { po.model.isAltered(); } //GUILayout.Label( "Y ", GUILayout.MaxWidth(12)); EditorGUI.BeginChangeCheck(); po.curve[i].position.y = EditorGUILayout.FloatField("Y ", po.curve[i].position.y, GUILayout.MinWidth(50)); if (EditorGUI.EndChangeCheck()) { po.model.isAltered(); } //GUI.Label(new Rect, "["+i+"] X:" ); //+ po.curve[i].position EditorGUILayout.EndHorizontal(); GUILayout.EndArea(); cur_y += 16; } cur_y += 16; EditorGUIUtility.labelWidth = origLabelWidth; return(cur_y); }
// DO THE ACTUAL SAVE public static void saveParametricObject(AXParametricObject po, bool withInputSubparts, string filepathname) { //Debug.Log(filepathname); //EditorUtility.DisplayDialog("Archimatix Library", "Saving to Library: This may take a few moments.", "Ok"); po.readIntoLibraryFromRelativeAXOBJPath = ArchimatixUtils.getRelativeFilePath(filepathname); Library.recentSaveFolder = System.IO.Path.GetDirectoryName(filepathname); // If this head po has a grouperKey, lose it! // This is because when it is later instantiated, // that grouper may not exist or may not be the desired place for this. po.grouperKey = null; // gather relations as you go... List <AXRelation> rels = new List <AXRelation>(); // BUILD JSON STRING StringBuilder sb = new StringBuilder(); sb.Append("{"); sb.Append("\"parametric_objects\":["); sb.Append(JSONSerializersAX.ParametricObjectAsJSON(po)); // gather rels foreach (AXParameter p in po.parameters) { foreach (AXRelation rr in p.relations) { if (!rels.Contains(rr)) { rels.Add(rr); } } } // SUB NODES if (withInputSubparts) { // GATHER SUB_NODES //Debug.Log("Start gather"); po.gatherSubnodes(); //Debug.Log("End gather"); foreach (AXParametricObject spo in po.subnodes) { //Debug.Log("-- " + spo.Name); sb.Append(',' + JSONSerializersAX.ParametricObjectAsJSON(spo)); // gather rels foreach (AXParameter p in spo.parameters) { foreach (AXRelation rr in p.relations) { if (!rels.Contains(rr)) { rels.Add(rr); } } } } } sb.Append("]"); // add relations to json string thecomma; // RELATIONS if (rels != null && rels.Count > 0) { sb.Append(", \"relations\": ["); // begin parametric_objects thecomma = ""; foreach (AXRelation rr in rels) { sb.Append(thecomma + rr.asJSON()); thecomma = ", "; } sb.Append("]"); } sb.Append("}"); // *** SAVE AS ASSET *** // Since we have added the newItem to the live library, // generating this new file will not force a recreation of the library from the raw JSON file. File.WriteAllText(filepathname, sb.ToString()); // THUMBNAIL TO PNG if (po.is2D()) { Library.cache2DThumbnail(po); } else { Thumbnail.BeginRender(); Thumbnail.render(po, true); Thumbnail.EndRender(); } //string thumb_filename = System.IO.Path.ChangeExtension(filepathname, ".png"); string filename = System.IO.Path.GetFileNameWithoutExtension(filepathname); string prefix = (po.is2D()) ? "zz-AX-2DLib-" : "zz-AX-3DLib-"; string thumb_filename = System.IO.Path.ChangeExtension(filepathname, ".jpg"); thumb_filename = thumb_filename.Replace(filename, prefix + filename); byte[] bytes = po.thumbnail.EncodeToJPG(); //File.WriteAllBytes(libraryFolder + "data/"+ po.Name + ".png", bytes); File.WriteAllBytes(thumb_filename, bytes); //AssetDatabase.Refresh(); string thumbnailRelativePath = ArchimatixUtils.getRelativeFilePath(thumb_filename); //Debug.Log(path); AssetDatabase.ImportAsset(thumbnailRelativePath); TextureImporter importer = AssetImporter.GetAtPath(thumbnailRelativePath) as TextureImporter; if (importer != null) { importer.textureType = TextureImporterType.GUI; importer.maxTextureSize = 256; #if UNITY_5_5_OR_NEWER importer.textureCompression = TextureImporterCompression.Uncompressed; #else importer.textureFormat = TextureImporterFormat.AutomaticTruecolor; #endif } AssetDatabase.WriteImportSettingsIfDirty(thumbnailRelativePath); // Save the recent path to prefs EditorPrefs.SetString("LastLibraryPath", System.IO.Path.GetDirectoryName(filepathname)); EditorUtility.DisplayDialog("Archimatix Library", "ParametricObject saved to " + System.IO.Path.GetDirectoryName(thumbnailRelativePath) + " as " + filename, "Great, thanks!"); Texture2D tex = (Texture2D)AssetDatabase.LoadAssetAtPath(thumbnailRelativePath, typeof(Texture2D)); LibraryItem newItem = new LibraryItem(po); newItem.icon = tex; ArchimatixEngine.library.addLibraryItemToList(newItem); ArchimatixEngine.library.sortLibraryItems(); ArchimatixEngine.saveLibrary(); AssetDatabase.Refresh(); //Debug.Log("yo 2"); //ArchimatixEngine.library.readLibraryFromFiles(); }