public override void calculateBounds() { AXParameter SelectedOutput = S_InputShape.getSelectedOutputParameter(); Paths paths = (SelectedOutput != null) ? SelectedOutput.getPaths() : null; //Debug.Log(parametricObject.Name + ": " + P_Output); if (paths == null) return; IntRect cb = Clipper.GetBounds(SelectedOutput.getPaths()); Vector3 size = new Vector3(cb.right-cb.left, cb.bottom-cb.top, 0);///Archimatix.IntPointPrecision; Vector3 center = new Vector3(cb.left+size.x/2, cb.top+size.y/2, 0); parametricObject.bounds = new Bounds( (center/AXGeometryTools.Utilities.IntPointPrecision-new Vector3(transX, transY, 0)), size/AXGeometryTools.Utilities.IntPointPrecision); }
// 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); }
// 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); //float scale = modifierCurve.Evaluate( vert.y) * (1-(twist*vert.y)); float scale = modifierCurve.Evaluate(vert.x); //vert = new Vector3(vert.x*scale, vert.y, vert.z*scale); Matrix4x4 warperM = planSpl.matrixAtLength(vert.x); 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));; // float len = Mathf.Sqrt(vert.x*vert.x + vert.z*vert.z); // // float new_x = vert.x;//+ 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(vert); } // ---------- EACH VERTEX ---------------------- m.vertices = verts; //} amesh.mesh.RecalculateNormals(); ax_meshes.Add(amesh); } parametricObject.bounds = inputSrc_po.bounds; parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); if (makeGameObjects) { return(parametricObject.makeGameObjectsFromAXMeshes(ax_meshes)); } } return(null); }
public override void drawControlHandles(ref List <string> visited, Matrix4x4 consumerM, bool beingDrawnFromConsumer) { Matrix4x4 prevHandlesMatrix = Handles.matrix; FreeCurve gener = (FreeCurve)parametricObject.generator; base.drawControlHandles(ref visited, consumerM, true); if (alreadyVisited(ref visited, "FreeCurveHandler")) { return; } AXParameter p = parametricObject.getParameter("Output Shape"); if (p == null || p.getPaths() == null) { return; } parametricObject.model.addActiveFreeCurve(parametricObject); Event e = Event.current; if (ArchimatixEngine.sceneViewState == ArchimatixEngine.SceneViewState.AddPoint && e.type == EventType.keyDown && (e.keyCode == KeyCode.Escape || e.keyCode == KeyCode.Return)) { ArchimatixEngine.setSceneViewState(ArchimatixEngine.SceneViewState.Default); e.Use(); } handlePoints = new List <Vector2>(); bool handleHasChanged = false; /* * Matrix4x4 context = parametricObject.model.transform.localToWorldMatrix * generator.parametricObject.worldDisplayMatrix; * if (generator.hasOutputsConnected() || parametricObject.is2D()) * context *= generator.localMatrix.inverse; * else * context *= parametricObject.getAxisRotationMatrix().inverse * generator.localMatrix.inverse * parametricObject.getAxisRotationMatrix(); * * Handles.matrix = context; */ Handles.matrix = parametricObject.model.transform.localToWorldMatrix * generator.parametricObject.worldDisplayMatrix; // * generator.localMatrix.inverse; float gridDim = parametricObject.model.snapSizeGrid * 100; // axis Handles.color = Color.red; Handles.DrawLine(new Vector3(-gridDim / 2, 0, 0), new Vector3(gridDim / 2, 0, 0)); Handles.color = Color.green; Handles.DrawLine(new Vector3(0, -gridDim / 2, 0), new Vector3(0, gridDim / 2, 0)); // grid if (ArchimatixEngine.snappingOn()) { Handles.color = new Color(1, .5f, .65f, .15f); } else { Handles.color = new Color(1, .5f, .65f, .05f); } AXEditorUtilities.DrawGrid3D(gridDim, parametricObject.model.snapSizeGrid); //Handles.matrix = Matrix4x4.identity; CurvePoint newCurvePoint = null;; int newCurvePointIndex = -1; if (parametricObject.curve != null) { //if (Event.current.type == EventType.mouseDown) // selectedIndex = -1; //Vector3 pos; for (int i = 0; i < parametricObject.curve.Count; i++) { //Debug.Log (i + ": "+ parametricObject.curve[i].position); // Control points in Curve bool pointIsSelected = (generator.selectedIndices != null && generator.selectedIndices.Contains(i)); Vector3 pos = new Vector3(parametricObject.curve[i].position.x, parametricObject.curve[i].position.y, 0); Handles.color = (pointIsSelected) ? Color.white : Color.magenta; float capSize = .13f * HandleUtility.GetHandleSize(pos); if (pointIsSelected) { capSize = .17f * HandleUtility.GetHandleSize(pos); } // POSITION //pos = new Vector3(parametricObject.curve[i].position.x, parametricObject.curve[i].position.y, 0); // pos = Handles.FreeMoveHandle( // pos, // Quaternion.identity, // capSize, // Vector3.zero, // (controlID, positione, rotation, size) => // { // if (GUIUtility.hotControl > 0 && controlID == GUIUtility.hotControl) // Debug.Log("YOP"); // Handles.SphereCap(controlID, positione, rotation, size); // }); pos = Handles.FreeMoveHandle( pos, Quaternion.identity, capSize, Vector3.zero, (controlID, position, rotation, size) => { if (GUIUtility.hotControl > 0 && controlID == GUIUtility.hotControl) { //Debug.Log("*** " + e.type + " -" + e.keyCode + "-"); // MOUSE DOWN ON HANDLE! Undo.RegisterCompleteObjectUndo(parametricObject.model, "FreeCurve"); //Debug.Log(controlID + ": " + e.type); ArchimatixEngine.selectedFreeCurve = gener; //Debug.Log("SELECT NODE " +i + " ci="+controlID); if (i == 0 && ArchimatixEngine.sceneViewState == ArchimatixEngine.SceneViewState.AddPoint) { generator.P_Output.shapeState = ShapeState.Closed; ArchimatixEngine.setSceneViewState(ArchimatixEngine.SceneViewState.Default); } else if (e.shift && !ArchimatixEngine.mouseIsDownOnHandle) { generator.toggleItem(i); } else if (gener.selectedIndices == null || gener.selectedIndices.Count < 2) { if (!generator.isSelected(i)) { generator.selectOnlyItem(i); } } ArchimatixEngine.isPseudoDraggingSelectedPoint = i; // CONVERT TO BEZIER if (e.alt) { gener.convertToBezier(i); } for (int j = 0; j < generator.P_Output.Dependents.Count; j++) { generator.P_Output.Dependents [j].parametricObject.generator.adjustWorldMatrices(); } ArchimatixEngine.mouseDownOnSceneViewHandle(); } Handles.SphereCap(controlID, position, rotation, size); }); // MID_SEGEMNET HANDLE if (i < parametricObject.curve.Count) { //Handles.matrix = parametricObject.model.transform.localToWorldMatrix * generator.parametricObject.worldDisplayMatrix * generator.localMatrix.inverse; Handles.color = Color.cyan; //Debug.Log("mid handle "+i); 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()) { pos = Vector2.Lerp(a.position, b.position, .5f); } else { Vector2 pt = FreeCurve.bezierValue(a, b, .5f); pos = (Vector3)pt; } EditorGUI.BeginChangeCheck(); #if UNITY_5_6_OR_NEWER pos = Handles.FreeMoveHandle( pos, Quaternion.identity, .06f * HandleUtility.GetHandleSize(pos), Vector3.zero, (controlID, positione, rotation, size, eventType) => { if (GUIUtility.hotControl > 0 && controlID == GUIUtility.hotControl) { ArchimatixEngine.selectedFreeCurve = gener; } Handles.CubeHandleCap(controlID, positione, rotation, size, eventType); }); #else pos = Handles.FreeMoveHandle( pos, Quaternion.identity, .06f * HandleUtility.GetHandleSize(pos), Vector3.zero, (controlID, positione, rotation, size) => { if (GUIUtility.hotControl > 0 && controlID == GUIUtility.hotControl) { ArchimatixEngine.selectedFreeCurve = gener; } Handles.CubeCap(controlID, positione, rotation, size); }); #endif if (EditorGUI.EndChangeCheck()) { // add point to spline at i using pos.x, pos.y Undo.RegisterCompleteObjectUndo(parametricObject.model, "New Midpoint"); //Debug.Log(pos); //Debug.Log(ArchimatixEngine.isPseudoDraggingSelectedPoint + " ::: " + (i)); //if (ArchimatixEngine.isPseudoDraggingSelectedPoint != (i+1)) if (ArchimatixEngine.isPseudoDraggingSelectedPoint == -1) { //Debug.Log("CREATE!!!!"); newCurvePoint = new CurvePoint(pos.x, pos.y); newCurvePointIndex = i + 1; parametricObject.curve.Insert(newCurvePointIndex, newCurvePoint); ArchimatixEngine.isPseudoDraggingSelectedPoint = newCurvePointIndex; generator.selectedIndex = newCurvePointIndex; generator.selectOnlyItem(newCurvePointIndex); } parametricObject.model.isAltered(); } } } // \loop // BEZIER HANDLES LOOP for (int i = 0; i < parametricObject.curve.Count; i++) { //Debug.Log (i + ": "+ parametricObject.curve[i].position); // Control points in Curve bool pointIsSelected = (generator.selectedIndices != null && generator.selectedIndices.Contains(i)); Vector3 pos = new Vector3(parametricObject.curve[i].position.x, parametricObject.curve[i].position.y, 0); Vector3 posA = new Vector3(parametricObject.curve[i].position.x + parametricObject.curve[i].localHandleA.x, parametricObject.curve[i].position.y + parametricObject.curve[i].localHandleA.y, 0); Vector3 posB = new Vector3(parametricObject.curve[i].position.x + parametricObject.curve[i].localHandleB.x, parametricObject.curve[i].position.y + parametricObject.curve[i].localHandleB.y, 0); Handles.color = (pointIsSelected) ? Color.white : Color.magenta; if (pointIsSelected) { Handles.color = Color.magenta; if (parametricObject.curve[i].isBezierPoint()) { Handles.color = Color.white; Handles.DrawLine(pos, posA); Handles.DrawLine(pos, posB); EditorGUI.BeginChangeCheck(); posA = Handles.FreeMoveHandle( posA, Quaternion.identity, .1f * HandleUtility.GetHandleSize(pos), Vector3.zero, Handles.SphereCap ); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(parametricObject.model, "FreeformShapee"); handleHasChanged = true; parametricObject.curve[i].setHandleA(new Vector2(posA.x, posA.y)); //parametricObject.curve[i].localHandleA = new Vector2(pos.x, pos.y) - parametricObject.curve[i].position; //parametricObject.model.generate("Move FreeForm Shape Handle"); parametricObject.model.isAltered(); } // HANDLE_B EditorGUI.BeginChangeCheck(); posB = Handles.FreeMoveHandle( posB, Quaternion.identity, .1f * HandleUtility.GetHandleSize(pos), Vector3.zero, Handles.SphereCap ); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(parametricObject.model, "FreeformShapee"); handleHasChanged = true; //parametricObject.curve[i].localHandleB = new Vector2(pos.x, pos.y) - parametricObject.curve[i].position; parametricObject.curve[i].setHandleB(new Vector2(posB.x, posB.y)); //parametricObject.model.generate("Move FreeForm Shape Handle"); parametricObject.model.isAltered(); } } } // selected } // \bezier handles loop if (handleHasChanged) { } } Handles.matrix = prevHandlesMatrix; }
// RAIL public void genrateRail() { // generate a rail for all three: difference, intersection, union if (inputs.Count == 0) { return; } PolyFillType subjPolyFillType = PolyFillType.pftNonZero; //if (hasHoles) //subjPolyFillType = PolyFillType.pftPositive; //* organize by solids, holes (from SOLID designation) and clippers (from VOID designation) Paths subjPaths = new Paths(); Paths clipPaths = new Paths(); AXParameter inp = null; AXParameter src = null; Paths segments = new Paths(); Path tmp = null; for (int i = 0; i < inputs.Count; i++) { inp = inputs [i]; src = inp.DependsOn; if (src == null) { continue; } Paths srcPaths = src.getPaths(); if (srcPaths == null) { continue; } if (inp.polyType == PolyType.ptSubject) { subjPaths.AddRange(srcPaths); foreach (Path sp in srcPaths) { // When clipping open shapes, don't add a closingsegment: int ender = (inp.shapeState == ShapeState.Open) ? sp.Count - 1 : sp.Count; for (int j = 0; j < ender; j++) { int next_j = (j == sp.Count - 1) ? 0 : j + 1; tmp = new Path(); tmp.Add(sp[j]); tmp.Add(sp[next_j]); segments.Add(tmp); } } //subjPaths.AddRange (src.getTransformedHolePaths()); } else if (inp.polyType == PolyType.ptClip) { clipPaths.AddRange(srcPaths); //clipPaths.AddRange (src.getTransformedHolePaths()); } else { continue; } } // turn subjs and holes into segments to be clipped // foreach(Path sp in subjPaths) // { // // each path // //int ender = // for(int i=0; i<sp.Count-1; i++) // { // int next_i = (i == sp.Count-1) ? 0 : i+1; // tmp = new Path(); // tmp.Add (sp[i]); // tmp.Add (sp[next_i]); // segments.Add(tmp); // } // } //Debug.Log ("segments"); //Archimatix.printPaths(segments); Clipper railc = new Clipper(Clipper.ioPreserveCollinear); if (segments != null) { railc.AddPaths(segments, PolyType.ptSubject, false); } if (clipPaths != null) { railc.AddPaths(clipPaths, PolyType.ptClip, true); } AXClipperLib.PolyTree solutionRail = new AXClipperLib.PolyTree(); // DIFFERENCE_RAIL if ((differenceRail.Dependents != null && differenceRail.Dependents.Count > 0) || combineType == CombineType.DifferenceRail) { railc.Execute(ClipType.ctDifference, solutionRail, subjPolyFillType, PolyFillType.pftNonZero); differenceRail.polyTree = null; differenceRail.paths = assembleRailPathsFromClippedSegments(solutionRail); if (differenceRail.paths.Count == 0) { differenceRail.paths = subjPaths; } alignPathsDirestionsWithSource(ref differenceRail.paths, ref segments); thickenAndOffset(ref differenceRail, differenceRail); } // INTERSECTION RAIL if ((intersectionRail.Dependents != null && intersectionRail.Dependents.Count > 0) || combineType == CombineType.IntersectionRail) { //railc.Execute(ClipType.ctIntersection, solutionRail, subjPolyFillType, PolyFillType.pftNonZero); railc.Execute(ClipType.ctIntersection, solutionRail, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); intersectionRail.polyTree = null; intersectionRail.paths = assembleRailPathsFromClippedSegments(solutionRail); if (intersectionRail.paths.Count == 0) { AXGeometryTools.Utilities.reversePaths(ref intersectionRail.paths); } alignPathsDirestionsWithSource(ref intersectionRail.paths, ref segments); thickenAndOffset(ref intersectionRail, intersectionRail); } }
/* * public override void initializeBays(string pName) * { * if (parametricObject.isInitialized) * return; * * parametricObject.isInitialized = true; * * RadialRepeaterTool gener = repeaterToolU as RadialRepeaterTool; * * switch(pName) * { * case "Node Shape": * if (repeaterToolU != null) * gener.radius = 3.5f * nodeSrc_p.parametricObject.bounds.size.x ; * break; * case "Cell Shape": * if (repeaterToolU != null) * gener.radius = 2.5f * cellSrc_p.parametricObject.bounds.size.x ; * break; * } * } */ // SHAPE_REPEATER_2D :: GENERATE public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (parametricObject == null || !parametricObject.isActive) { return(null); } if ((P_Corner == null || cornerSrc_p == null) && (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); } // PRE_GENERATE preGenerate(); planSrc_p = P_Plan.DependsOn; // getUpstreamSourceParameter(P_Plan); planSrc_po = (planSrc_p != null) ? planSrc_p.parametricObject : null; 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); } } } AXParameter P_cornerOutput = new AXParameter(); P_cornerOutput.parametricObject = parametricObject; AXParameter P_nodeOutput = new AXParameter(); P_nodeOutput.parametricObject = parametricObject; AXParameter P_cellOutput = new AXParameter(); P_cellOutput.parametricObject = parametricObject; // PROCESS SHAPE INPUTS if (cornerSrc_p != null) { P_Corner.polyTree = null; AXShape.thickenAndOffset(ref P_Corner, cornerSrc_p); } if (inputSrc_p != null) { P_Node.polyTree = null; AXShape.thickenAndOffset(ref P_Node, inputSrc_p); } if (cellSrc_p != null) { P_Cell.polyTree = null; AXShape.thickenAndOffset(ref P_Cell, cellSrc_p); } bool doPolyTreeNodes = false; //bool doPolyTreeCells = false; // NODE //Matrix4x4 tm = Matrix4x4.identity; // NODE SHAPES Paths nodeSourcePaths = null; //Clipper nodeClipper = null; if (P_Node != null) { if (P_Node.polyTree != null) { nodeSourcePaths = AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_Node.polyTree)); doPolyTreeNodes = true; //nodeClipper = new Clipper(); } else { nodeSourcePaths = P_Node.getClonePaths(); P_nodeOutput.paths = new Paths(); } } // CELL SHAPES Paths cellSourcePaths = null; //Clipper cellClipper = null; if (P_Cell != null) { if (P_Cell.polyTree != null) { cellSourcePaths = AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_Cell.polyTree)); doPolyTreeNodes = true; //cellClipper = new Clipper(); } else { cellSourcePaths = P_Cell.getClonePaths(); P_cornerOutput.paths = new Paths(); } } // BREAK CORNER SHAPES Paths cornerSourcePaths = null; Clipper cornerClipper = null; if (P_Corner != null) { if (P_Corner.polyTree != null) { cornerSourcePaths = AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_Corner.polyTree)); doPolyTreeNodes = true; cornerClipper = new Clipper(); } else { cornerSourcePaths = P_Corner.getClonePaths(); P_cornerOutput.paths = new Paths(); } } // FOR EACH PATH for (int path_i = 0; path_i < planPaths.Count; path_i++) { // **** 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.Log("planSpline.subsplines.Count="+ planSpline.subsplines.Count ); // foreach(SubsplineIndices si in planSpline.subsplines) // si.print(); planSpline.groupNearBreakAngleVertices(inset * 2); // **** PREPARE EACH SPLINE *** // Matrix4x4 localPlacement_mx = Matrix4x4.identity; if (planSpline.insetSpanSplines != null && planSpline.insetSpanSplines.Count > 0) { for (int si = 0; si < planSpline.insetSpanSplines.Count; si++) { planSpline.insetSpanSplines[si].setRepeaterTransforms(si, inset, bay); } // SPAN NODES - SHAPES ALONG SUBSPLINES if (nodeSrc_p != null && nodeSrc_p.meshes != null) { 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]; List <Matrix4x4> nodeMatrices = spanSpline.repeaterNodeTransforms; // on each of these nodes, place a nodePlug instance. bool spanNodesAtBreakCorners = true; int starter = spanNodesAtBreakCorners ? 0 : 1; int ender = (inset > 0 || spanNodesAtBreakCorners) ? nodeMatrices.Count : nodeMatrices.Count - 1; //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); if (doPolyTreeNodes) { cornerClipper.AddPaths(AX.Generators.Generator2D.transformPaths(nodeSourcePaths, localPlacement_mx), PolyType.ptSubject, true); } else { Paths tmp = AX.Generators.Generator2D.transformPaths(nodeSourcePaths, localPlacement_mx); P_cornerOutput.paths.AddRange(tmp); } } } } } // CELL NODES - SHAPES ALONG SUBSPLINES if (cellSrc_p != null && cellSrc_p.meshes != null) { 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]; List <Matrix4x4> cellMatrices = spanSpline.repeaterCellTransforms; // on each of these nodes, place a nodePlug instance. bool spanNodesAtBreakCorners = true; int starter = spanNodesAtBreakCorners ? 0 : 1; int ender = (inset > 0 || spanNodesAtBreakCorners) ? cellMatrices.Count : cellMatrices.Count - 1; //string this_address = ""; if (cellMatrices != null) { for (int ii = starter; ii < ender; ii++) { //this_address = "cell_"+path_i+"_"+i+"_"+ii; //Debug.Log("this_address="+this_address); // LOCAL_PLACEMENT localPlacement_mx = localMatrixFromAddress(RepeaterItem.Cell, path_i, i, ii); if (doPolyTreeNodes) { cornerClipper.AddPaths(AX.Generators.Generator2D.transformPaths(cellSourcePaths, localPlacement_mx), PolyType.ptSubject, true); } else { Paths tmp = AX.Generators.Generator2D.transformPaths(nodeSourcePaths, localPlacement_mx); P_cornerOutput.paths.AddRange(tmp); } } } } } } if (cornerSourcePaths != null && cornerSourcePaths.Count > 0) { // CORNERS for (int bi = 0; bi < planSpline.breakIndices.Count; bi++) { //tm = Matrix4x4.TRS(new Vector3(2*i-2, 2*j-2, 0), Quaternion.identity, Vector3.one); localPlacement_mx = localMatrixFromAddress(RepeaterItem.Corner, path_i, planSpline.breakIndices[bi]); if (doPolyTreeNodes) { cornerClipper.AddPaths(AX.Generators.Generator2D.transformPaths(cornerSourcePaths, localPlacement_mx), PolyType.ptSubject, true); } else { Paths tmp = AX.Generators.Generator2D.transformPaths(cornerSourcePaths, localPlacement_mx); P_cornerOutput.paths.AddRange(tmp); } } } if (doPolyTreeNodes) { P_cornerOutput.polyTree = new AXClipperLib.PolyTree(); cornerClipper.Execute(ClipType.ctDifference, P_cornerOutput.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero); } } P_Output.polyTree = null; if (cornerSrc_p != null || cellSrc_p == null || nodeSrc_p == null) { // JUST NODES AXShape.thickenAndOffset(ref P_Output, P_cornerOutput); } /* * else 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
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; 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.DependsOn; 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; 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); AXParameter sHeight = prototypeSrc_po.getParameter("Height"); sHeight.initiateRipple_setFloatValueFromGUIChange(h); prototypeSrc_po.generator.pollControlValuesFromParmeters(); prototypeSrc_po.isAltered = true; replicant = prototypeSrc_po.generateOutputNow(makeGameObjects, parametricObject, true); 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 WINWALL 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); } planIsClosed = (P_Plan.hasThickness || P_Plan.shapeState == ShapeState.Closed) ? true : false; P_Plan.polyTree = null; Paths planPaths = planSrc_p.getPaths(); Path planPath = planPaths[0]; Spline planSpline = new Spline(planPath, planIsClosed, P_Plan.breakGeom, P_Plan.breakNorm); Paths offsetPaths = Pather.wallOffsets(planSpline, .5f, .5f); Pather.printPaths(offsetPaths); // each path, step through and mak a rectangle // segment wide and height and then subtract windows. //Then make poly and add to combiner Path window = AXTurtle.Rectangle(1, 1, false); //window.Reverse(); Pather.shiftPath(window, new IntPoint(10000, 5000)); Debug.Log("=========="); Pather.printPath(window); Pather rightPather = new Pather(offsetPaths[0]); int[] rightLengths = rightPather.segment_lengths; for (int i = 0; i < rightLengths.Length; i++) { Debug.Log(rightLengths[i]); int next_i = (i == rightLengths.Length - 1) ? 0 : i + 1; Path rect = AXTurtle.Rectangle(rightLengths[next_i] / 10000f, 3, false); Clipper c = new Clipper(); c.AddPath(rect, PolyType.ptSubject, true); // fenestration c.AddPath(window, PolyType.ptClip, true); AXClipperLib.PolyTree polytree = new AXClipperLib.PolyTree(); c.Execute(ClipType.ctDifference, polytree, PolyFillType.pftNonZero, PolyFillType.pftNonZero); Paths pathResult = Clipper.PolyTreeToPaths(polytree); Pather.printPaths(pathResult); Mesh mesh = AXPolygon.triangulate(polytree, new AXTexCoords()); Matrix4x4 wallm = Matrix4x4.TRS(new Vector3(offsetPaths[0][i].X / 10000f, 0, offsetPaths[0][i].Y / 10000f), Quaternion.Euler(-90, planSpline.edgeRotations[i], 0), Vector3.one); ax_meshes.Add(new AXMesh(mesh, wallm)); } parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter); // FINISH BOUNDING setBoundaryFromAXMeshes(ax_meshes); if (makeGameObjects) { return(parametricObject.makeGameObjectsFromAXMeshes(ax_meshes)); } return(null); }