/// <summary> /// Computes the error. /// </summary> /// <returns>The error.</returns> /// <param name="n">Number of variables</param> /// <param name="x">Variable Initial Values</param> public new double ComputeError(int n, double[] x) { double alpha = x[0]; bestFitInterval = new int[] { }; Curve curve = perpGeodesics[startIndex]; Point3d pt = curve.PointAt(perpParameters[startIndex]); Vector3d vector = curve.TangentAt(perpParameters[startIndex]); MeshPoint mPt = mesh.ClosestMeshPoint(pt, 0.0); Vector3d normal = mesh.NormalAt(mPt); Vector3d cP = Vector3d.CrossProduct(vector, normal); cP.Rotate(alpha, normal); if (refDir == Vector3d.Unset) { refDir = cP; } double angle = Vector3d.VectorAngle(cP, refDir); Vector3d.VectorAngle(cP, refDir); Curve newG = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, pt, cP, maxIter).ToNurbsCurve(); if (newG == null) { return(100000000); } if (bothDir) { Curve newG2 = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, pt, -cP, maxIter).ToNurbsCurve(); newG2.Reverse(); newG = Curve.JoinCurves(new List <Curve> { newG, newG2 })[0]; } // Assign resulting geodesic to global property for output. selectedGeodesic = newG; // Calculate error double error = 0; List <double> distances = new List <double>(); List <double> signedDistances = new List <double>(); List <double> errorValues = new List <double>(); for (int i = 0; i < perpGeodesics.Count - 1; i++) { Curve g = perpGeodesics[i]; CurveIntersections cvInt = Intersection.CurveCurve(newG, g, 0.00001, 0.00001); double signedDistance = g.GetLength(new Interval(0, perpParameters[i])); signedDistances.Add(signedDistance); if (cvInt.Count > 0) { // Compute distance if intersection is found double param = cvInt[0].ParameterB; double distance = g.GetLength(new Interval(0, param)); distances.Add(distance); // Add squared distance to error error += Math.Pow(signedDistance - distance, 2); } else { // Penalize if no intersection is found on this perp geodesic distances.Add(1000); error += 1000; } } //Calculate longest interval within threshold. for (int k = (distances.Count - 1); k >= 1; k--) { for (int i = 0; i < (distances.Count - k); i++) { //Check if interval i->k is within bounds bool flag = true; for (int j = i; j < i + k; j++) { double Lbound = signedDistances[j] * (1 - threshold); double Ubound = signedDistances[j] * (1 + threshold); if (Lbound > distances[j] || distances[j] > Ubound) { flag = false; break; } } if (flag && bestFitInterval.Length == 0) { bestFitInterval = new int[] { i, i + k }; } } } if (bestFitInterval.Length == 0) { error += 1000000; return(error); } double fixedError = 0; for (int index = bestFitInterval[0]; index == bestFitInterval[1]; index++) { fixedError += Math.Pow(signedDistances[index] - distances[index], 2); } fixedError /= (bestFitInterval[1] - bestFitInterval[0]); //error = error / (bestFitInterval[1] - bestFitInterval[0]); //if (invertDir) selectedGeodesic.Reverse(); return(fixedError); }
internal BeamPolycut(AdvanceSteel.Nodes.SteelDbObject element, int cutShapeRectCircle, Autodesk.AdvanceSteel.Geometry.Point3d insertPoint, Autodesk.AdvanceSteel.Geometry.Vector3d normal, Autodesk.AdvanceSteel.Geometry.Vector3d lengthVector, int corner, List <Property> beamFeatureProperties) { lock (access_obj) { using (var ctx = new SteelServices.DocContext()) { List <Property> defaultData = beamFeatureProperties.Where(x => x.Level == ".").ToList <Property>(); List <Property> postWriteDBData = beamFeatureProperties.Where(x => x.Level == "Z_PostWriteDB").ToList <Property>(); double length = 0; double width = 0; double radius = 0; if (defaultData.FirstOrDefault <Property>(x => x.Name == "Length") != null) { length = (double)defaultData.FirstOrDefault <Property>(x => x.Name == "Length").InternalValue; } if (defaultData.FirstOrDefault <Property>(x => x.Name == "Width") != null) { width = (double)defaultData.FirstOrDefault <Property>(x => x.Name == "Width").InternalValue; } if (defaultData.FirstOrDefault <Property>(x => x.Name == "Radius") != null) { radius = (double)defaultData.FirstOrDefault <Property>(x => x.Name == "Radius").InternalValue; } string existingFeatureHandle = SteelServices.ElementBinder.GetHandleFromTrace(); string elementHandle = element.Handle; FilerObject obj = Utils.GetObject(elementHandle); BeamMultiContourNotch beamFeat = null; if (obj != null && obj.IsKindOf(FilerObject.eObjectType.kBeam)) { if (string.IsNullOrEmpty(existingFeatureHandle) || Utils.GetObject(existingFeatureHandle) == null) { Beam bmObj = obj as Beam; switch (cutShapeRectCircle) { case 0: beamFeat = new BeamMultiContourNotch(bmObj, (Beam.eEnd) 1, insertPoint, normal, lengthVector, length, width); break; case 1: beamFeat = new BeamMultiContourNotch(bmObj, (Beam.eEnd) 1, insertPoint, normal, lengthVector, radius); break; } Vector2d offset; switch (corner) { case 0: //Top Left offset = new Vector2d(-1, 1); break; case 1: //Top Right offset = new Vector2d(1, 1); break; case 2: //Bottom Right offset = new Vector2d(1, -1); break; case 3: //Bottom left offset = new Vector2d(-1, -1); break; default: //Anything else ignore offset = new Vector2d(0, 0); break; } beamFeat.Offset = offset; if (defaultData != null) { Utils.SetParameters(beamFeat, defaultData); } bmObj.AddFeature(beamFeat); if (postWriteDBData != null) { Utils.SetParameters(beamFeat, postWriteDBData); } } else { beamFeat = Utils.GetObject(existingFeatureHandle) as BeamMultiContourNotch; if (beamFeat != null && beamFeat.IsKindOf(FilerObject.eObjectType.kBeamMultiContourNotch)) { beamFeat.End = (Beam.eEnd) 0; Matrix3d cutMatrix = beamFeat.CS; Point3d orgin = null; Vector3d xVec = null; Vector3d yVec = null; Vector3d zVec = null; cutMatrix.GetCoordSystem(out orgin, out xVec, out yVec, out zVec); xVec = new Vector3d(lengthVector); yVec = xVec.CrossProduct(normal); zVec = xVec.CrossProduct(yVec); cutMatrix.SetCoordSystem(insertPoint, xVec, yVec, zVec); beamFeat.CS = cutMatrix; Vector2d offset; switch (corner) { case 0: //Top Left offset = new Vector2d(-1, 1); break; case 1: //Top Right offset = new Vector2d(1, 1); break; case 2: //Bottom Right offset = new Vector2d(1, -1); break; case 3: //Bottom left offset = new Vector2d(-1, -1); break; default: //Anything else ignore offset = new Vector2d(0, 0); break; } beamFeat.Offset = offset; if (defaultData != null) { Utils.SetParameters(beamFeat, defaultData); } if (postWriteDBData != null) { Utils.SetParameters(beamFeat, postWriteDBData); } } else { throw new System.Exception("Not a Beam Feature"); } } } else { throw new System.Exception("No Input Element found"); } Handle = beamFeat.Handle; SteelServices.ElementBinder.CleanupAndSetElementForTrace(beamFeat); } } }
public PressureGoal(PlanktonMesh mesh, double p, bool option) { pMesh = (PlanktonMesh)mesh; //Pressure pres0 = Math.Abs(p); // Unit: [N/m2] / [Pa] pres1 = pres0; if (p < 0.0) { negativePres = true; } else { negativePres = false; } //Calculate starting volume vol0 = 0.0; // Unit: [m3] for (int j = 0; j < pMesh.Faces.Count; j++) { int[] faceVertices = pMesh.Faces.GetFaceVertices(j); Point3d pA = new Point3d(pMesh.Vertices[faceVertices[0]].X, pMesh.Vertices[faceVertices[0]].Y, pMesh.Vertices[faceVertices[0]].Z); Point3d pB = new Point3d(pMesh.Vertices[faceVertices[1]].X, pMesh.Vertices[faceVertices[1]].Y, pMesh.Vertices[faceVertices[1]].Z); Point3d pC = new Point3d(pMesh.Vertices[faceVertices[2]].X, pMesh.Vertices[faceVertices[2]].Y, pMesh.Vertices[faceVertices[2]].Z); Point3d pD = new Point3d(0, 0, 0); Vector3d AB = pB - pA; Vector3d AC = pC - pA; Vector3d AD = pD - pA; Vector3d cross = Vector3d.CrossProduct(AB, -AC); double dot = Vector3d.Multiply(cross, AD); double v = (1.0 / 6.0) * dot; vol0 += v; } vol1 = vol0; //Gas constant and temperature gasConst = 8.314472; // Unit: [J/(K*mol)] temp = 273 + 20; // Unit: [Kelvins] Set to 20 degrees by default //Molecules mol0 = (pres0 * vol0) / (gasConst * temp); // Unit: [moles] mol1 = mol0; opt = option; PPos = new Point3d[pMesh.Vertices.Count]; Move = new Vector3d[pMesh.Vertices.Count]; Weighting = new double[pMesh.Vertices.Count]; for (int i = 0; i < pMesh.Vertices.Count; i++) { PPos[i] = new Point3d(pMesh.Vertices[i].X, pMesh.Vertices[i].Y, pMesh.Vertices[i].Z); Move[i] = new Vector3d(0, 0, 0); Weighting[i] = 1.0; } }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { List <Mesh> M = new List <Mesh>(); if (!DA.GetDataList(0, M)) { return; } double A = 0; DA.GetData(1, ref A); double D = 0; DA.GetData(2, ref D); double biAng = 0; Point3d current, previous, next; List <Point3d> flapPoints; Vector3d incoming, outgoing, zAxis, biSect, vPrev, vNext; int cW; DataTree <Polyline> Flaps = new DataTree <Polyline>(); DataTree <GH_Line> FoldInnerEdges = new DataTree <GH_Line>(); DataTree <GH_Line> FoldOuterEdges = new DataTree <GH_Line>(); for (int k = 0; k < M.Count; k++) { FoldInnerEdges.AddRange(GetClothedEdges(M[k]).Select(l => new GH_Line(l)).ToArray(), new GH_Path(k)); Polyline[] nakedEdges = M[k].GetNakedEdges(); Polyline[] flapCurves = new Polyline[nakedEdges.Length]; // verify that naked edges are closed polylines bool isClosed = true; foreach (Polyline nEdge in nakedEdges) { isClosed &= nEdge.IsClosed; } if (!isClosed) { return; } for (int i = 0; i < nakedEdges.Length; i++) { // add segments to outer edges Data Tree FoldOuterEdges.AddRange(nakedEdges[i].GetSegments().Select(s => new GH_Line(s)).ToArray(), new GH_Path(k)); cW = IsClockWise(nakedEdges[i]) ? -1 : 1; // is polyline clockwise? flapPoints = new List <Point3d>(); // remove duplicate point at start/endpoint nakedEdges[i].RemoveAt(nakedEdges[i].Count - 1); int nPoints = nakedEdges[i].Count; int prevInd, nextInd; Vector3d[,] OffsetVectors = new Vector3d[nPoints, 2]; double[] OffsetAngles = new double[nPoints]; // find bisector vectors and angles for (int j = 0; j < nPoints; j++) { prevInd = (j - 1 + nPoints) % nPoints; nextInd = (j + 1) % nPoints; current = nakedEdges[i][j]; previous = nakedEdges[i][prevInd]; next = nakedEdges[i][nextInd]; incoming = previous - current; outgoing = next - current; double incomingLength = incoming.Length; double outgoingLength = outgoing.Length; incoming.Unitize(); outgoing.Unitize(); zAxis = Vector3d.CrossProduct(incoming, outgoing) * cW; // check if this elbow is convex or concave (referring to the angle inside the polyline) int convex = IsConvex(cW, current, incoming, outgoing, out biAng) ? cW : -cW; // angle correction to get the exact bisector angle biAng *= 0.5; biSect = -(incoming + outgoing) * convex;// * cW; biSect.Unitize(); // rotation & angle check double angle = A < biAng ? A * convex * cW : biAng * convex * cW; // vectors for incoming and outgoing directions from a vertex vPrev = incoming; vNext = outgoing; double dist = D / Math.Abs(Math.Sin(angle)); //double distP = D / Math.Abs(Math.Sin(angle)); // length check double maxLPrev, maxLNext; maxLPrev = incomingLength * 0.5 / Math.Abs(Math.Cos(angle)); maxLNext = outgoingLength * 0.5 / Math.Abs(Math.Cos(angle)); vPrev *= Math.Min(dist, maxLPrev); //dist; vNext *= Math.Min(dist, maxLNext); //dist; vPrev.Rotate(-angle, zAxis); vNext.Rotate(angle, zAxis); OffsetVectors[j, 0] = vPrev; OffsetVectors[j, 1] = vNext; OffsetAngles[j] = angle; } double hMin, hsFactorStart, hsFactorEnd; Vector3d vStart, vEnd; Point3d fStart, fEnd; // verify offsets and generate flap points for (int j = 0; j < nPoints; j++) { nextInd = (j + 1) % nPoints; current = nakedEdges[i][j]; vStart = OffsetVectors[j, 1]; vEnd = OffsetVectors[nextInd, 0]; hsFactorStart = Math.Abs(Math.Sin(OffsetAngles[j])); hsFactorEnd = Math.Abs(Math.Sin(OffsetAngles[nextInd])); hMin = Math.Min(vStart.Length * hsFactorStart, vEnd.Length * hsFactorEnd); vStart.Unitize(); vEnd.Unitize(); vStart *= hMin / hsFactorStart; vEnd *= hMin / hsFactorEnd; // generate flap points and add them to the array fStart = current + vStart; fEnd = nakedEdges[i][nextInd] + vEnd; flapPoints.Add(current); flapPoints.Add(fStart); flapPoints.Add(fEnd); } // add again first point to get closed polyline flapPoints.Add(flapPoints[0]); flapCurves[i] = new Polyline(flapPoints); } Flaps.AddRange(flapCurves, new GH_Path(k)); } DA.SetDataTree(0, FoldInnerEdges); DA.SetDataTree(1, FoldOuterEdges); DA.SetDataTree(2, Flaps); }
public override void Calculate(List <Particle> p) { Point3d P0 = p[PIndex[0]].Position; Point3d P1 = p[PIndex[1]].Position; Point3d P2 = p[PIndex[2]].Position; Point3d P3 = p[PIndex[3]].Position; Vector3d V01 = P1 - P0; Vector3d V02 = P2 - P0; Vector3d V03 = P3 - P0; Vector3d V21 = P1 - P2; Vector3d V31 = P1 - P3; double L01 = V01.Length; double invL01 = 1.0 / L01; //get heights //there is some re-use possible here to speed up double H0 = (V02 - V02 * invL01 * invL01 * V01 * V01).Length; double H1 = (V03 - V03 * invL01 * invL01 * V01 * V01).Length; double H = 0.5 / (H0 + H1); double Dot0201 = V02 * V01; double Dot0301 = V03 * V01; double Dot2101 = V21 * V01; double Dot3101 = V31 * V01; //Cot is dot over mag of cross //Get normals Vector3d Cross0 = Vector3d.CrossProduct(V02, V01); Vector3d Cross1 = Vector3d.CrossProduct(V01, V03); double CurrentAngle = Vector3d.VectorAngle(Cross0, Cross1, new Plane(P0, V01)); if (CurrentAngle > Math.PI) { CurrentAngle = CurrentAngle - 2 * Math.PI; } double AngleError = CurrentAngle - RestAngle; double InvL = 1.0 / Cross0.Length; double Cot0u = Dot0201 * InvL; double Cot0v = Dot2101 * InvL; InvL = 1.0 / Cross1.Length; double Cot1u = Dot0301 * InvL; double Cot1v = Dot3101 * InvL; double D = AngleError * H * 0.5; Vector3d A = Cross0 * D; Move[0] = Cot0v * A; Move[1] = Cot0u * A; Move[2] = -(Cot0v + Cot0u) * A; A = Cross1 * D; Move[0] += Cot1v * A; Move[1] += Cot1u * A; Move[3] = -(Cot1v + Cot1u) * A; Weighting[0] = Strength; Weighting[1] = Strength; Weighting[2] = Strength; Weighting[3] = Strength; }
public static bool TryGetExtrusion(this Surface surface, out Extrusion extrusion) { extrusion = null; var nurbsSurface = surface as NurbsSurface ?? surface.ToNurbsSurface(); for (int direction = 1; direction >= 0; --direction) { var oposite = direction == 0 ? 1 : 0; if (surface.IsClosed(direction)) { continue; } var domain = nurbsSurface.Domain(direction); var iso0 = nurbsSurface.IsoCurve(oposite, domain.Min); var iso1 = nurbsSurface.IsoCurve(oposite, domain.Max); if (iso0.TryGetPlane(out var plane0) && iso1.TryGetPlane(out var plane1)) { if (plane0.Normal.IsParallelTo(plane1.Normal, RhinoMath.DefaultAngleTolerance / 100.0) == 1) { var rowCount = direction == 0 ? nurbsSurface.Points.CountU : nurbsSurface.Points.CountV; var columnCount = direction == 0 ? nurbsSurface.Points.CountV : nurbsSurface.Points.CountU; for (int c = 0; c < columnCount; ++c) { var point = direction == 0 ? nurbsSurface.Points.GetControlPoint(0, c) : nurbsSurface.Points.GetControlPoint(c, 0); for (int r = 1; r < rowCount; ++r) { var pointR = direction == 0 ? nurbsSurface.Points.GetControlPoint(r, c) : nurbsSurface.Points.GetControlPoint(c, r); var projectedPointR = plane0.ClosestPoint(pointR.Location); if (projectedPointR.DistanceToSquared(point.Location) > RhinoMath.SqrtEpsilon) { return(false); } if (Math.Abs(pointR.Weight - point.Weight) > RhinoMath.ZeroTolerance) { return(false); } } } // Extrusion.Create does not work well when 'iso0' is a line-like curve, // plane used to extrude is "arbitrary" in this case //extrusion = Extrusion.Create(iso0, zAxis.Length, false); var axis = new Line(iso0.PointAtStart, iso1.PointAtStart); var zAxis = iso1.PointAtStart - iso0.PointAtStart; var xAxis = (iso0.IsClosed ? iso0.PointAt(iso0.Domain.Mid) : iso0.PointAtEnd) - iso0.PointAtStart; var yAxis = Vector3d.CrossProduct(zAxis, xAxis); extrusion = new Extrusion(); if (!iso0.Transform(Transform.PlaneToPlane(new Plane(iso0.PointAtStart, xAxis, yAxis), Plane.WorldXY))) { return(false); } return(extrusion.SetPathAndUp(axis.From, axis.To, yAxis) && extrusion.SetOuterProfile(iso0, false)); } } } return(false); }
public static Plane PlaneFromNormalAndYAxis(Point3d origin, Vector3d normal, Vector3d yaxis) { return(new Plane(origin, Vector3d.CrossProduct(yaxis, normal), yaxis)); }
public static Polyline[] OffsetPolyline(Polyline c0, Polyline c1, double toolr = 10, bool notch = false) { if (toolr == 0) { return new Polyline[] { c0, c1 } } ; if (c0.Count == 2) { return new Polyline[] { c0, c1 } } ; Transform transform = OrientTo2D(c0); Polyline ply0 = new Polyline(c0); Polyline ply1 = new Polyline(c1); bool closed = c0[0].DistanceToSquared(c0[c0.Count - 1]) < 0.001; if (!closed) { ply0.Close(); ply1.Close(); } ply0.Transform(transform); ply1.Transform(transform); Transform inverse; transform.TryGetInverse(out inverse); Plane ply0Plane = ply0.plane(); Plane ply1Plane = ply1.plane(); Polyline pl0Offset = new Polyline(); Polyline pl1Offset = new Polyline(); string orient = (IsClockwiseClosedPolylineOnXYPlane(ply0)) ? "CounterClockwise" : "Clockwise"; if (ply0.IsValid && ply1.IsValid) { Point3d[] vrts = ply0.ToArray(); Point3d[] uvrts = ply1.ToArray(); Plane notPairingPlane; Plane.FitPlaneToPoints(vrts, out notPairingPlane); //int k = 1; //int infeed = 1; //Rhino.RhinoApp.WriteLine(k.ToString()); //ncc.Add("(start infeed no" + k.ToString() + ")"); for (int i = 0; i != vrts.Length - 1; i++) // iterate segments { Point3d p0 = vrts[i]; //#always Point3d p0u = uvrts[i]; Point3d p2b = new Point3d(); Point3d p1b = new Point3d(); Point3d p1 = new Point3d(); Point3d p2 = new Point3d(); Point3d p1u = new Point3d(); if (i == 0) { p2b = vrts[vrts.Length - 3]; p1b = vrts[vrts.Length - 2]; p1 = vrts[i + 1]; p2 = vrts[i + 2]; p1u = uvrts[i + 1]; } else if (i == 1) { p2b = vrts[vrts.Length - 2]; p1b = vrts[i - 1]; p1 = vrts[i + 1]; p2 = vrts[i + 2]; p1u = uvrts[i + 1]; } else if (i == vrts.Length - 2) { p2b = vrts[i - 2]; p1b = vrts[i - 1]; p1 = vrts[0]; p2 = vrts[1]; p1u = uvrts[0]; } else if (i == vrts.Length - 3) { p2b = vrts[i - 2]; p1b = vrts[i - 1]; p1 = vrts[i + 1]; p2 = vrts[0]; p1u = uvrts[i + 1]; } else { p2b = vrts[i - 2]; p1b = vrts[i - 1]; p1 = vrts[i + 1]; p2 = vrts[i + 2]; p1u = uvrts[i + 1]; } // ## DET TOOLPATH Vector3d n1b = Rhino.Geometry.Vector3d.CrossProduct(p1b - p0, p0u - p0); //#Srf Normal (last) Vector3d n0 = Rhino.Geometry.Vector3d.CrossProduct(p0 - p1, p0u - p0); //#Srf Normal (current) Vector3d n1 = Rhino.Geometry.Vector3d.CrossProduct(p2 - p1, p1u - p1); //#Srf Normal (next) n1b.Unitize(); n1b *= toolr * -1; n0.Unitize(); n0 *= toolr; n1.Unitize(); n1 *= toolr; Plane pl0 = new Plane(p0, (n1b + n0) / 2); //# ext bisector plane last/current Plane pl1 = new Plane(p1, ((n0 + n1) / 2)); //# ext bisector plane current/next Line ln0 = new Line(p0 + (n0 * -1), p1 + (n0 * -1)); //# toolpath Line double pm0; double pm1; Rhino.Geometry.Intersect.Intersection.LinePlane(ln0, pl0, out pm0); Rhino.Geometry.Intersect.Intersection.LinePlane(ln0, pl1, out pm1); Point3d pt0 = ln0.PointAt(pm0); //# intersection with Plane 0 Point3d pt1 = ln0.PointAt(pm1); //# intersection with Plane 1 Point3d pt6 = new Point3d(); bool boolN = false; Vector3d n44 = p1u - p1; n44.Unitize(); Point3d ptXX = pt1 + n44 * 45; Line XXA = new Line(p1, p1u); Point3d ptC = XXA.ClosestPoint(pt1, false); double l0 = ptC.DistanceTo(pt1) - toolr; //# offset dist Vector3d nnn = ptC - pt1; nnn.Unitize(); Point3d pt3 = pt1 + nnn * l0; Point3d pt4 = pt3 + (p1u - p1); Line ln1 = new Line(pt3, pt4); //# cylinder axis //## IDENTIFY INSIDE CORNERS Vector3d r1l = p2b - p1b; //# last back Vector3d r1n = p0 - p1b; //# last front Vector3d al = p1b - p0; //# current back Vector3d an = p1 - p0; //# current front Vector3d bl = p0 - p1; //# next back Vector3d bn = p2 - p1; //# next front r1l.Unitize(); r1n.Unitize(); al.Unitize(); an.Unitize(); bl.Unitize(); bn.Unitize(); Vector3d cpr1 = Vector3d.CrossProduct(r1l, r1n); //# +- look 1 back Vector3d cp0 = Vector3d.CrossProduct(al, an); //# +- look current Vector3d cp1 = Vector3d.CrossProduct(bl, bn); //# +- look 1 ahead if (orient == "Clockwise") { if (cpr1.Z < 0 && cp0.Z < 0 && cp1.Z > 0) //# --+ { boolN = true; } else if (cpr1.Z < 0 && cp0.Z > 0 && cp1.Z > 0) //# -++ { boolN = true; } else if (cpr1.Z > 0 && cp0.Z < 0 && cp1.Z > 0) //# +-+ { boolN = true; } } else if (orient == "CounterClockwise") { if (cp0.Z > 0) //# +-+ { boolN = true; } } Point3d[] pts = { pt0, pt1, pt1 + (p1u - p1), pt0 + (p0u - p0) }; //Vector3d nh0 = ((pts[3] - pts[0]) / infeed) * (k - 1); //Vector3d nh1 = ((pts[2] - pts[1]) / infeed) * (k - 1); Point3d p21 = pts[1]; //+ nh1; // infeed pts Point3d p30 = pts[0]; //+ nh0; int IPDtemp = 3; // division for sim mach if (Math.Abs(pts[0].DistanceTo(pts[1])) <= Math.Abs(pts[3].DistanceTo(pts[2])) + 0.5 && Math.Abs(pts[0].DistanceTo(pts[1])) >= Math.Abs(pts[3].DistanceTo(pts[2])) - 0.5) { IPDtemp = 1; // simple cut } // List<Point3d> ptsl = IBOIS.Utilities.GeometryProcessing.DividePoints(pts[0], pts[1], IPDtemp); // List<Point3d> ptsm = IBOIS.Utilities.GeometryProcessing.DividePoints(p30, p21, IPDtemp); //List<Point3d> ptsu = IBOIS.Utilities.GeometryProcessing.DividePoints(pts[3], pts[2], IPDtemp); // Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(pts[0]); //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Line(p30,p21)); // Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Line(pts[0], pts[1])); // Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Line(pts[3], pts[2])); //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(new Line(pts[0], pts[3])); double t; Line line = new Line(pts[0], pts[3]); Rhino.Geometry.Intersect.Intersection.LinePlane(line, ply0Plane, out t); pl0Offset.Add(line.PointAt(t)); Rhino.Geometry.Intersect.Intersection.LinePlane(line, ply1Plane, out t); pl1Offset.Add(line.PointAt(t)); } } //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(pl0Offset); if (notch) { //notches List <Line> notches = DrillingHoleForConvexCorners(ply0, ply1, -toolr); //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(pl0Offset); //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(pl1Offset); int counter = 0; for (int i = 0; i < notches.Count; i++) { if ((!closed) && (i == 0 || i == (notches.Count - 1))) { continue; } if (notches[i] == Line.Unset) { continue; } //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(notches[i]); pl0Offset.Insert(i + 1 + counter, notches[i].From);//i+1 because after point pl1Offset.Insert(i + 1 + counter, notches[i].To); counter++; pl0Offset.Insert(i + 1 + counter, pl0Offset[i - 1 + counter]); pl1Offset.Insert(i + 1 + counter, pl1Offset[i - 1 + counter]); counter++; } } if (closed) { pl0Offset.Close(); pl1Offset.Close(); } pl0Offset.Transform(inverse); pl1Offset.Transform(inverse); return(new Polyline[] { pl0Offset, pl1Offset }); }
public SimplePipeJoint(Point3d p1, Point3d p2, Point3d p3, double pipeWidth, Solution sol, bool needId) : base(sol, needId) { this.Style = sol.CurrentLineStyle; this.SplitLines = new List <ObjectId>(); this.p1 = p1; this.p2 = p2; this.p3 = p3; CenterPoint = p2; Vector3d d1 = (p2 - p1).GetNormal(); Vector3d d2 = (p3 - p2).GetNormal(); Vector3d d3 = (d2 - d1).GetNormal(); //角平分线 double cos1 = d3.DotProduct(-d1); double sin1 = Math.Sqrt(1 - cos1 * cos1); double R1 = jointRadius / sin1; Point3d center = p2 + R1 * d3; Point3d arcStartPoint = p2 - R1 * cos1 * d1; Point3d arcEndPoint = p2 + R1 * cos1 * d2; Point3d arcCenterPoint = center - d3 * jointRadius; CircularArc3d c = new CircularArc3d(arcStartPoint, arcCenterPoint, arcEndPoint); double angle1 = c.ReferenceVector.AngleOnPlane(new Plane(c.Center, c.Normal)); arc = new Arc(); arc.Center = c.Center; arc.Radius = c.Radius; arc.Normal = c.Normal; arc.StartAngle = c.StartAngle + angle1; arc.EndAngle = c.EndAngle + angle1; double angle = d2.GetAngleTo(d1); if (d1.CrossProduct(d2).Z < 0) { angle = -angle; } int seg = 3; if (Math.Abs(angle) < Math.PI / 2) { seg = 3; } else if (Math.Abs(angle) < Math.PI / 4 * 3) { seg = 4; } else { seg = 5; } polyline = new Polyline(); double ShortR = jointRadius - pipeWidth; double WideR = jointRadius + pipeWidth; Vector3d d4 = (arcStartPoint - center).GetNormal(); Point3d p4 = center + d4 * ShortR; Point3d p5 = center + d4 * WideR; lines = new List <Line>(); for (int i = 0; i < seg - 1; i++) { Point3d p6; Point3d p7; if (i == 0) { d4 = d4.RotateBy(angle / (seg - 1) / 2, Vector3d.ZAxis); } else { d4 = d4.RotateBy(angle / (seg - 1), Vector3d.ZAxis); } p6 = center + d4 * ShortR; p7 = center + d4 * WideR; Line l = new Line(p6, p7); lines.Add(l); } Vector3d d5 = (arcEndPoint - center).GetNormal(); Point3d p8 = center + d5 * ShortR; Point3d p9 = center + d5 * WideR; polyline.AddVertexAt(0, new Point2d(p4.X, p4.Y), 0, 0, 0); for (int i = 0; i < lines.Count; i++) { Point3d p = lines[i].StartPoint; polyline.AddVertexAt(i + 1, new Point2d(p.X, p.Y), 0, 0, 0); } polyline.AddVertexAt(lines.Count + 1, new Point2d(p8.X, p8.Y), 0, 0, 0); polyline.AddVertexAt(lines.Count + 2, new Point2d(p9.X, p9.Y), 0, 0, 0); for (int i = lines.Count - 1; i >= 0; i--) { Point3d p = lines[i].EndPoint; polyline.AddVertexAt(lines.Count + 2 + lines.Count - i, new Point2d(p.X, p.Y), 0, 0, 0); } polyline.AddVertexAt(2 * lines.Count + 3, new Point2d(p5.X, p5.Y), 0, 0, 0); polyline.AddVertexAt(2 * lines.Count + 4, new Point2d(p4.X, p4.Y), 0, 0, 0); //save all objects this.SaveEntities(); }
public List <Point3d> GenerateFromCrossPipe(PipeLine line, Point3d sPoint, Point3d ePoint, double width) { List <Point3d> res = new List <Point3d>(); //计算与mline的交点 Point3d sm = line.Point(0); Point3d em = line.Point(1); Vector3d v1 = (em - sm).GetNormal(); Vector3d n1 = v1.RotateBy(0.5 * Math.PI, Vector3d.ZAxis); Point3d p1 = sm + line.Width * n1; Point3d p2 = em + line.Width * n1; Point3d p3 = sm - line.Width * n1; Point3d p4 = em - line.Width * n1; Point3d centerPoint = Utils.Utility.CrossPoint(sm, em, sPoint, ePoint); Vector3d v2 = (ePoint - sPoint).GetNormal(); double len1 = line.Width / Math.Abs(v2.DotProduct(n1)); Point3d p5 = centerPoint + v2 * len1; double cos1 = v2.DotProduct(v1); double sin1 = Math.Sqrt(1 - cos1 * cos1); Point3d p6 = p5 - v1 * (width / sin1); Point3d p7 = p5 + v1 * (width / sin1); int sign; if (v2.CrossProduct(v1).Z > 0) { sign = 1; } else { sign = -1; } Point3d p8 = (centerPoint - Length * v1) - n1 * width * sign; Point3d p9 = (centerPoint + Length * v1) - n1 * width * sign; Point3d e1 = centerPoint - Length * v1; Point3d e2 = centerPoint + Length * v1; Point3d p10 = e1 + (e1 - p8); Point3d p11 = e2 + (e2 - p9); Point3d p13 = centerPoint + Length * v2; Vector3d n2 = v2.RotateBy(sign * 0.5 * Math.PI, Vector3d.ZAxis); Point3d p14 = p13 - n2 * width; Point3d p15 = p13 + n2 * width; pline.AddVertexAt(0, Utils.Utility.Point3DTo2D(p8), 0, 0, 0); pline.AddVertexAt(1, Utils.Utility.Point3DTo2D(p6), 0, 0, 0); pline.AddVertexAt(2, Utils.Utility.Point3DTo2D(p14), 0, 0, 0); pline.AddVertexAt(3, Utils.Utility.Point3DTo2D(p15), 0, 0, 0); pline.AddVertexAt(4, Utils.Utility.Point3DTo2D(p7), 0, 0, 0); pline.AddVertexAt(5, Utils.Utility.Point3DTo2D(p9), 0, 0, 0); pline.AddVertexAt(6, Utils.Utility.Point3DTo2D(p11), 0, 0, 0); pline.AddVertexAt(7, Utils.Utility.Point3DTo2D(p10), 0, 0, 0); pline.AddVertexAt(8, Utils.Utility.Point3DTo2D(p8), 0, 0, 0); Line l1 = new Line(e1, centerPoint); Line l2 = new Line(e2, centerPoint); Line l3 = new Line(p13, centerPoint); lines.Add(l1); lines.Add(l2); lines.Add(l3); SaveEntity(); res.Add(e1); res.Add(e2); res.Add(p13); CenterPoint = centerPoint; return(res); }
public override void Calculate() { Paths = new List <Path>(); foreach (Polyline P in DriveCurves) { if (P.Count < 2) { continue; } if (StartEnd) { P.Reverse(); } Path OP = new Path(); Vector3d tan, x, t1, t2; Plane p; double angle; if (!P.IsClosed) { #region FirstPlane tan = new Vector3d(P[1] - P[0]).ProjectToPlane(Workplane); tan.Unitize(); x = Vector3d.CrossProduct(tan, Workplane.ZAxis); p = new Plane(P[0], x, tan); p.Origin = p.Origin + Tool.Diameter / 2 * p.XAxis * ToolOffset; OP.Add(p); #endregion #region MiddlePlanes for (int i = 1; i < P.Count - 1; ++i) { t1 = new Vector3d(P[i] - P[i + 1]).ProjectToPlane(Workplane); t2 = new Vector3d(P[i] - P[i - 1]).ProjectToPlane(Workplane); t1.Unitize(); t2.Unitize(); angle = Vector3d.VectorAngle(t1, t2); tan = t2 - t1; tan.Unitize(); x = Vector3d.CrossProduct(tan, Workplane.ZAxis); p = new Plane(P[i], x, tan); p.Origin = p.Origin + (Tool.Diameter / 2) / Math.Sin(angle / 2) * p.XAxis * ToolOffset; OP.Add(p); } #endregion #region LastPlane tan = new Vector3d(P[P.Count - 1] - P[P.Count - 2]).ProjectToPlane(Workplane); tan.Unitize(); x = Vector3d.CrossProduct(tan, Workplane.ZAxis); p = new Plane(P[P.Count - 1], x, tan); p.Origin = p.Origin + Tool.Diameter / 2 * p.XAxis * ToolOffset; OP.Add(p); #endregion } else { int N = P.Count - 1; int next, prev; for (int i = 0; i < N; ++i) { next = (i + 1).Modulus(N); prev = (i - 1).Modulus(N); t1 = new Vector3d(P[i] - P[next]).ProjectToPlane(Workplane); t2 = new Vector3d(P[i] - P[prev]).ProjectToPlane(Workplane); t1.Unitize(); t2.Unitize(); angle = Vector3d.VectorAngle(t1, t2); tan = t2 - t1; tan.Unitize(); x = Vector3d.CrossProduct(tan, Workplane.ZAxis); p = new Plane(P[i], x, tan); p.Origin = p.Origin + (Tool.Diameter / 2) / Math.Sin(angle / 2) * p.XAxis * ToolOffset; OP.Add(p); } OP.Add(OP[0]); } Paths.Add(OP); } }
public static DataTree <Polyline> ReciprocalFrame(this Mesh mesh, double angle = 10, double dist = 0.25, double width = 0.1) { DataTree <Polyline> polylines = new DataTree <Polyline>(); try { var display = new List <Line>(); double thickness = width; int[][] tv = mesh.GetNGonsTopoBoundaries(); HashSet <int> tvAll = mesh.GetAllNGonsTopoVertices(); HashSet <int> e = mesh.GetAllNGonEdges(tv); Line[] lines = mesh.GetAllNGonEdgesLines(e); Line[] lines1 = mesh.GetAllNGonEdgesLines(e); bool[] nakedV = mesh.GetNakedEdgePointStatus(); int[][] fe = mesh.GetNGonFacesEdges(tv); Plane[] planes = new Plane[lines.Length]; Vector3d[] vecs = new Vector3d[mesh.TopologyEdges.Count]; int j = 0; foreach (int i in e) { Line l = mesh.TopologyEdges.EdgeLine(i); Rhino.IndexPair ip = mesh.TopologyEdges.GetTopologyVertices(i); int v0 = mesh.TopologyVertices.MeshVertexIndices(ip.I)[0]; int v1 = mesh.TopologyVertices.MeshVertexIndices(ip.J)[0]; Vector3d vec = new Vector3d( (mesh.Normals[v0].X + mesh.Normals[v1].X) * 0.5, (mesh.Normals[v0].Y + mesh.Normals[v1].Y) * 0.5, (mesh.Normals[v0].Z + mesh.Normals[v1].Z) * 0.5 ); vec.Unitize(); vecs[j] = vec; if (mesh.TopologyEdges.GetConnectedFaces(i).Length == 2) { l.Transform(Transform.Rotation(Rhino.RhinoMath.ToRadians(angle), vec, l.PointAt(0.5))); } Vector3d cross = Vector3d.CrossProduct(l.Direction, vec); planes[j] = new Plane(l.PointAt(0.5), cross); cross.Unitize(); l.Transform(Transform.Translation(cross * thickness)); lines[j] = l; l.Transform(Transform.Translation(-cross * 2 * thickness)); lines1[j++] = l; } //ngon vertex edges int[][] connectedE = mesh.GetConnectedNGonEdgesToNGonTopologyVertices(tvAll, e); int[] allEArray = e.ToArray(); int[] allvArray = tvAll.ToArray(); Line[] linesCopy = new Line[lines.Length]; Line[] linesCopy1 = new Line[lines.Length]; Line[] linesCopyM = new Line[lines.Length]; Line[] linesCopyM1 = new Line[lines.Length]; // Line[] linesCopyMoved = new Line[lines.Length]; for (int i = 0; i < lines.Length; i++) { linesCopy[i] = new Line(lines[i].From, lines[i].To); linesCopy1[i] = new Line(lines1[i].From, lines1[i].To); linesCopyM[i] = new Line(lines[i].From + vecs[i] * dist, lines[i].To + vecs[i] * dist); linesCopyM1[i] = new Line(lines1[i].From + vecs[i] * dist, lines1[i].To + vecs[i] * dist); } for (int i = 0; i < connectedE.Length; i++) { //Defines planes int total = connectedE[i].Length; Plane[] projectionPlanes = new Plane[total]; int start = total - 1; for (j = start; j < start + total; j++) { int currentEdge = connectedE[i][j % total]; int localID = Array.IndexOf(allEArray, currentEdge); projectionPlanes[j - start] = planes[localID]; } //Intersect lines for (j = 0; j < connectedE[i].Length; j++) { int currentEdge = connectedE[i][j]; if (mesh.TopologyEdges.GetConnectedFaces(currentEdge).Length == 1) { continue; } int localID = Array.IndexOf(allEArray, currentEdge); Line currentLine = linesCopy[localID]; Line currentLine1 = linesCopy1[localID]; Line currentLineM = linesCopyM[localID]; Line currentLineM1 = linesCopyM1[localID]; IndexPair pair = mesh.TopologyEdges.GetTopologyVertices(currentEdge); double lineT, lineT1; Plane currentPlane = new Plane(projectionPlanes[j]); double flag = 1; //Check length Plane tempPlane = new Plane(currentPlane); Line temp2 = new Line(currentLine.From, currentLine.To); tempPlane.Origin += tempPlane.ZAxis * (thickness); Line temp = new Line(currentLine.From, currentLine.To); double tt; Rhino.Geometry.Intersect.Intersection.LinePlane(temp2, tempPlane, out tt); if (allvArray[i] == pair.I) { temp.From = temp2.PointAt(tt); } else { temp.To = temp2.PointAt(tt); } double lineLen0 = temp.Length; tempPlane = new Plane(currentPlane); temp2 = new Line(currentLine.From, currentLine.To); tempPlane.Origin += tempPlane.ZAxis * (-thickness); temp = new Line(currentLine.From, currentLine.To); Rhino.Geometry.Intersect.Intersection.LinePlane(temp2, tempPlane, out tt); if (allvArray[i] == pair.I) { temp.From = temp2.PointAt(tt); } else { temp.To = temp2.PointAt(tt); } double lineLen1 = temp.Length; //End Check Length if (lineLen1 < lineLen0) { flag = -1; } currentPlane.Origin += currentPlane.ZAxis * (flag * thickness); Rhino.Geometry.Intersect.Intersection.LinePlane(currentLine, currentPlane, out lineT); Rhino.Geometry.Intersect.Intersection.LinePlane(currentLine1, currentPlane, out lineT1); Rhino.Geometry.Intersect.Intersection.LinePlane(currentLineM, currentPlane, out lineT); Rhino.Geometry.Intersect.Intersection.LinePlane(currentLineM1, currentPlane, out lineT1); if (allvArray[i] == pair.I) { currentLine.From = currentLine.PointAt(lineT); currentLine1.From = currentLine1.PointAt(lineT1); currentLineM.From = currentLineM.PointAt(lineT); currentLineM1.From = currentLineM1.PointAt(lineT1); } else { currentLine.To = currentLine.PointAt(lineT); currentLine1.To = currentLine1.PointAt(lineT1); currentLineM.To = currentLineM.PointAt(lineT); currentLineM1.To = currentLineM1.PointAt(lineT1); } linesCopy[localID] = currentLine; linesCopy1[localID] = currentLine1; linesCopyM[localID] = currentLineM; linesCopyM1[localID] = currentLineM1; } } for (int i = 0; i < linesCopy.Length; i++) { if (mesh.TopologyEdges.GetConnectedFaces(allEArray[i]).Length == 1) { continue; } polylines.AddRange(new Polyline[] { new Polyline(new Point3d[] { linesCopy[i].From, linesCopy[i].To, linesCopy1[i].To, linesCopy1[i].From, linesCopy[i].From }), new Polyline(new Point3d[] { linesCopyM[i].From, linesCopyM[i].To, linesCopyM1[i].To, linesCopyM1[i].From, linesCopyM[i].From }) }, new GH_Path(i)); } //A = linesCopy; //B = linesCopy1; //C = linesCopyM; //D = linesCopyM1; //E = polylines; } catch (Exception e) { Rhino.RhinoApp.WriteLine(e.ToString()); } return(polylines); }
public void TestViewDir(ScreenAxisRotation axis) { Document doc = AcadApp.DocumentManager.MdiActiveDocument; ViewTableRecord vtr = doc.Editor.GetCurrentView(); Vector3d dirVectorInitial = vtr.ViewDirection; Vector3d sideVectorAxis = dirVectorInitial.GetPerpendicularVector(); // If there is existing ViewTwist angle // rotate the side vector with that angle // so it will coincide with the side vector if (vtr.ViewTwist > 1e-6) { sideVectorAxis = sideVectorAxis.RotateBy(-vtr.ViewTwist, dirVectorInitial); } Vector3d upVectorAxis = dirVectorInitial.CrossProduct(sideVectorAxis).GetNormal(); Vector3d axisRotation = new Vector3d(); switch (axis) { case ScreenAxisRotation.SideAxis: axisRotation = sideVectorAxis; break; case ScreenAxisRotation.UpAxis: axisRotation = upVectorAxis; break; case ScreenAxisRotation.Twist: break; default: break; } double angle5deg = 0.0872664626; for (int i = 0; i < 72; i++) { Thread.Sleep(50); // By X axis vtr.ViewDirection = vtr.ViewDirection.RotateBy(angle5deg, sideVectorAxis); upVectorAxis = upVectorAxis.RotateBy(angle5deg, sideVectorAxis); vtr.ViewTwist = AutoCADManager.CalcViewTwist(doc, vtr); doc.Editor.SetCurrentView(vtr); // By Y axis vtr.ViewDirection = vtr.ViewDirection.RotateBy(angle5deg, upVectorAxis); sideVectorAxis = sideVectorAxis.RotateBy(angle5deg, upVectorAxis); vtr.ViewTwist = AutoCADManager.CalcViewTwist(doc, vtr); doc.Editor.SetCurrentView(vtr); doc.Editor.Regen(); } angle5deg *= -1; for (int i = 72; i > 0; i--) { Thread.Sleep(50); // By Y axis vtr.ViewDirection = vtr.ViewDirection.RotateBy(angle5deg, upVectorAxis); sideVectorAxis = sideVectorAxis.RotateBy(angle5deg, upVectorAxis); vtr.ViewTwist = AutoCADManager.CalcViewTwist(doc, vtr); doc.Editor.SetCurrentView(vtr); // By X axis vtr.ViewDirection = vtr.ViewDirection.RotateBy(angle5deg, sideVectorAxis); upVectorAxis = upVectorAxis.RotateBy(angle5deg, sideVectorAxis); vtr.ViewTwist = AutoCADManager.CalcViewTwist(doc, vtr); doc.Editor.SetCurrentView(vtr); doc.Editor.Regen(); } }
static public double DistancePointLine(Point3d M, Point3d A, Point3d B) { return(Vector3d.CrossProduct(M - A, M - B).Length / (A - B).Length); }
public override bool Construct(bool append = false) { if (!append) { foreach (var part in Parts) { part.Geometry.Clear(); } } var bPart = Beam; var beam = (bPart.Element as BeamElement).Beam; var v0beam = (V0.Element as BeamElement).Beam; var v1beam = (V1.Element as BeamElement).Beam; var bplane = beam.GetPlane(bPart.Parameter); int sign = 1; var v0Crv = (V0.Element as BeamElement).Beam.Centreline; if ((bplane.Origin - v0Crv.PointAt(v0Crv.Domain.Mid)) * bplane.XAxis > 0) { sign = -1; } // Get point and normal of intersection var points = new Point3d[3]; var vectors = new Vector3d[3]; var average = Point3d.Origin; for (int i = 0; i < Parts.Length; ++i) { var crv = (Parts[i].Element as BeamElement).Beam.Centreline; points[i] = crv.PointAt(Parts[i].Parameter); vectors[i] = crv.TangentAt(Parts[i].Parameter); var midpt = crv.PointAt(crv.Domain.Mid); if ((points[i] - midpt) * vectors[i] < 0) { vectors[i] = -vectors[i]; } average = average + points[i]; } average = average / 3; // Create dividing surface for V-beams var tangent = (vectors[0] + vectors[1]) / 2; tangent.Unitize(); var normal = Vector3d.CrossProduct(vectors[0], vectors[1]); var binormal = Vector3d.CrossProduct(tangent, normal); Point3d vpt0, vpt1; var res = v0beam.Centreline.ClosestPoints(v1beam.Centreline, out vpt0, out vpt1); var vx = (vpt0 + vpt1) / 2; var vv0 = JointUtil.GetEndConnectionVector(v0beam, vx); var vv1 = JointUtil.GetEndConnectionVector(v1beam, vx); var yaxis = (v0beam.GetPlane(V0.Parameter).YAxis + v1beam.GetPlane(V1.Parameter).YAxis) / 2; var v0plane = v0beam.GetPlane(vx); var v1plane = v1beam.GetPlane(vx); var xaxis0 = v0plane.XAxis; var xaxis1 = v1plane.XAxis; if (xaxis1 * xaxis0 < 0) { xaxis1 = -xaxis1; } yaxis = Vector3d.CrossProduct(xaxis0, xaxis1); var divPlane = new Plane(vx, (vv0 + vv1) / 2, yaxis); var divider = Brep.CreatePlanarBreps(new Curve[] { new Rectangle3d(divPlane, new Interval(-300, 300), new Interval(-300, 300)).ToNurbsCurve() }, 0.01); //vj.V0.Geometry.AddRange(divider); V1.Geometry.AddRange(divider); // Create temporary plate var plane = new Plane(average, binormal, tangent); // Create trimmer on bottom of Beam var trimPlane = new Plane(bplane.Origin + bplane.XAxis * beam.Width * 0.5 * -sign, bplane.ZAxis, bplane.YAxis); var trimmers = Brep.CreatePlanarBreps(new Curve[] { new Rectangle3d(trimPlane, new Interval(-300, 300), new Interval(-300, 300)).ToNurbsCurve() }, 0.01); var sillPlane = new Plane(bplane.Origin + bplane.XAxis * beam.Width * 0.5 * sign, bplane.ZAxis, bplane.YAxis); var sillTrimmer = Brep.CreatePlanarBreps(new Curve[] { new Rectangle3d(sillPlane, new Interval(-300, 300), new Interval(-300, 300)).ToNurbsCurve() }, 0.01); var proj = sillPlane.ProjectAlongVector(divPlane.XAxis); V0.Geometry.AddRange(trimmers); V1.Geometry.AddRange(trimmers); V1.Geometry.AddRange(sillTrimmer); // Create cutter for through-tenon (V0) var zz = trimPlane.Project(divPlane.ZAxis); zz.Unitize(); var yy = trimPlane.Project(divPlane.YAxis); yy.Unitize(); var origin = divPlane.Origin; origin.Transform(proj); double zheight = 100.0; double tenonWidth = 60.0; var srfsTop = new Brep[3]; sign = divPlane.ZAxis * vv0 < 0 ? 1 : -1; var p = new Point3d[9]; for (int i = -1; i < 2; i += 2) { var srfs = new Brep[3]; p[0] = origin + yy * tenonWidth * 0.5 * i; p[1] = p[0] + divPlane.XAxis * 200.0; p[2] = p[1] + yy * zheight * i; p[3] = p[0] + yy * zheight * i; p[4] = p[0] - zz * 100 * sign; p[5] = p[4] + yy * zheight * i; p[6] = p[1] + zz * 100 * sign; p[7] = p[6] - divPlane.XAxis * 500.0; p[8] = p[4] - divPlane.XAxis * 300.0; var poly = new Polyline(new Point3d[] { p[0], p[1], p[6], p[7], p[8], p[4], p[0] }); srfs[0] = Brep.CreateFromCornerPoints(p[0], p[1], p[2], p[3], 0.01); srfs[1] = Brep.CreateFromCornerPoints(p[0], p[3], p[5], p[4], 0.01); srfs[2] = Brep.CreatePlanarBreps(new Curve[] { poly.ToNurbsCurve() }, 0.01)[0]; var joined = Brep.JoinBreps(srfs, 0.01); V0.Geometry.AddRange(joined); } // Create cutter for tenon cover (V1) normal = Vector3d.CrossProduct(zz, divPlane.XAxis); var tPlane = new Plane(origin, normal); var ww = tPlane.Project(vv0); var vv = tPlane.Project(vv1); var buttPlane = new Plane(v0plane.Origin + v0plane.XAxis * v0beam.Width / 2, v0plane.ZAxis, v0plane.YAxis); var proj2 = buttPlane.ProjectAlongVector(divPlane.XAxis); var origin2 = origin; origin2.Transform(proj2); var srfs2 = new Brep[3]; p[0] = origin2 + yy * tenonWidth * 0.5 + ww * 20.0; p[1] = p[0] - ww * 200.0; p[2] = p[1] - vv * 500.0; p[3] = p[0] - vv * 500.0; p[4] = origin2 - yy * tenonWidth * 0.5 + ww * 20.0; p[5] = p[4] - ww * 200.0; p[6] = p[5] - vv * 500.0; p[7] = p[4] - vv * 500.0; srfs2[0] = Brep.CreateFromCornerPoints(p[0], p[1], p[2], p[3], 0.01); srfs2[1] = Brep.CreateFromCornerPoints(p[4], p[5], p[6], p[7], 0.01); srfs2[2] = Brep.CreateFromCornerPoints(p[0], p[1], p[5], p[4], 0.01); var joined2 = Brep.JoinBreps(srfs2, 0.01); V1.Geometry.AddRange(joined2); // Create cutter for beam (Beam) var dot = vv0 * trimPlane.ZAxis; var srfTenon = new Brep[4]; double hw = v0beam.Width * 0.5 / dot; // TODO int flip = -1; for (int i = 0; i < 2; i++) { p[0 + 4 * i] = origin + yy * tenonWidth * 0.5 + zz * hw - ww * 150.0 * flip; p[1 + 4 * i] = origin + yy * tenonWidth * 0.5 - zz * hw - ww * 150.0 * flip; p[2 + 4 * i] = origin - yy * tenonWidth * 0.5 - zz * hw - ww * 150.0 * flip; p[3 + 4 * i] = origin - yy * tenonWidth * 0.5 + zz * hw - ww * 150.0 * flip; flip = -flip; } srfTenon[0] = Brep.CreateFromCornerPoints(p[0], p[1], p[5], p[4], 0.01); srfTenon[1] = Brep.CreateFromCornerPoints(p[1], p[2], p[6], p[5], 0.01); srfTenon[2] = Brep.CreateFromCornerPoints(p[2], p[3], p[7], p[6], 0.01); srfTenon[3] = Brep.CreateFromCornerPoints(p[3], p[0], p[4], p[7], 0.01); var joinedTenon = Brep.JoinBreps(srfTenon, 0.01); Beam.Geometry.AddRange(joinedTenon); return(true); }
/// <summary> /// Glulam factory methods. /// </summary> /// <param name="curve">Input curve.</param> /// <param name="planes">Input orientation planes.</param> /// <param name="data">Input glulam data.</param> /// <returns>New glulam.</returns> static public Glulam CreateGlulam(Curve curve, Plane[] planes = null, GlulamData data = null) { if (data == null) { data = GlulamData.FromCurveLimits(curve); } Glulam glulam; if (planes == null || planes.Length < 1) // if there are no planes defined, create defaults { Plane p; if (curve.IsLinear(Tolerance)) { curve.PerpendicularFrameAt(curve.Domain.Min, out p); glulam = new StraightGlulam(curve, new Plane[] { p }); } else if (curve.IsPlanar(Tolerance)) { curve.TryGetPlane(out p, Tolerance); glulam = new SingleCurvedGlulam(curve, new Plane[] { new Plane( curve.PointAtStart, p.ZAxis, Vector3d.CrossProduct( curve.TangentAtStart, p.ZAxis ) ), new Plane( curve.PointAtEnd, p.ZAxis, Vector3d.CrossProduct( curve.TangentAtEnd, p.ZAxis ) ) }); } else { Plane start, end; curve.PerpendicularFrameAt(curve.Domain.Min, out start); curve.PerpendicularFrameAt(curve.Domain.Max, out end); glulam = new DoubleCurvedGlulam(curve, new Plane[] { start, end }); } } else // if there are planes defined { if (curve.IsLinear(Tolerance)) { if (planes.Length == 1) { glulam = new StraightGlulam(curve, planes); } else { glulam = new StraightGlulam(curve, planes, true); // glulam = new StraightGlulamWithTwist(curve, planes); Console.WriteLine("Not implemented..."); } } else if (curve.IsPlanar(Tolerance)) { Plane crv_plane; curve.TryGetPlane(out crv_plane); /* * Are all the planes perpendicular to the curve normal? * Yes: basic SC Glulam * Are all the planes consistently aligned from the curve normal? * Yes: SC Glulam with rotated cross-section * SC Glulam with twisting */ bool HasTwist = false; foreach (Plane p in planes) { if (Math.Abs(p.XAxis * crv_plane.ZAxis) > Tolerance) { HasTwist = true; } } if (HasTwist) { glulam = new DoubleCurvedGlulam(curve, planes); } else { Plane first = new Plane(curve.PointAtStart, crv_plane.ZAxis, Vector3d.CrossProduct(curve.TangentAtStart, crv_plane.ZAxis)); Plane last = new Plane(curve.PointAtEnd, crv_plane.ZAxis, Vector3d.CrossProduct(curve.TangentAtEnd, crv_plane.ZAxis)); glulam = new SingleCurvedGlulam(curve, new Plane[] { first, last }); } } else { Plane temp; double t; bool Twisted = false; curve.PerpendicularFrameAt(curve.Domain.Min, out temp); double Angle = Vector3d.VectorAngle(planes[0].YAxis, temp.YAxis); for (int i = 0; i < planes.Length; ++i) { curve.ClosestPoint(planes[i].Origin, out t); curve.PerpendicularFrameAt(t, out temp); if (Math.Abs(Vector3d.VectorAngle(planes[0].YAxis, temp.YAxis) - Angle) > AngleTolerance) { // Twisting Glulam Twisted = true; break; } } /* * Are all the planes consistently aligned from some plane? * Yes: DC Glulam with constant cross-section * Are all the planes at a consistent angle from the perpendicular frame of the curve? * Yes: DC Glulam with minimal twisting * DC Glulam with twisting */ if (Twisted) { // TODO: differentiate between DC Glulam with minimal twist, and DC Glulam with twist glulam = new DoubleCurvedGlulam(curve, planes); } else { glulam = new DoubleCurvedGlulam(curve, planes); } } } //glulam.ValidateFrames(); int nh = data.NumHeight; int nw = data.NumWidth; if (glulam is DoubleCurvedGlulam) { if (data.NumHeight < 2) { nh = 2; data.LamHeight /= 2; } if (data.NumWidth < 2) { nw = 2; data.LamWidth /= 2; } data.Lamellae.ResizeArray(nw, nh); } else if (glulam is SingleCurvedGlulam) { if (data.NumHeight < 2) { nh = 2; data.LamHeight /= 2; } data.Lamellae.ResizeArray(nw, nh); } glulam.Data = data; return(glulam); }
public Point3D GetOrientation() { // Use Force as objective vector to rotate angles var vector = new Vector3d(Force); vector.Unitize(); // Define global axis var x1 = new Vector3d(Vector3d.XAxis); var x2 = new Vector3d(Vector3d.YAxis); var x3 = new Vector3d(Vector3d.ZAxis); // Get new Axis var x1Prime = Vector3d.CrossProduct(vector, x3); x1Prime.Unitize(); var x2Prime = Vector3d.CrossProduct(vector, x1Prime); x1Prime.Unitize(); var x3Prime = vector; // Get Rotation Matrix double m11 = Vector3d.Multiply(x1, x1Prime); var m12 = Vector3d.Multiply(x1, x2Prime); var m13 = Vector3d.Multiply(x1, x3Prime); var m21 = Vector3d.Multiply(x2, x1Prime); var m22 = Vector3d.Multiply(x2, x2Prime); var m23 = Vector3d.Multiply(x2, x3Prime); var m31 = Vector3d.Multiply(x3, x1Prime); var m32 = Vector3d.Multiply(x3, x2Prime); var m33 = Vector3d.Multiply(x3, x3Prime); // Get Euler angles var theta = 0.0; var psi = 0.0; var phi = 0.0; if ((!(m31 == 1)) && (!(m31 == -1))) { theta = -Math.Asin(m31); psi = Math.Atan2(m32 / Math.Cos(theta), m33 / Math.Cos(theta)); phi = Math.Atan2(m21 / Math.Cos(theta), m11 / Math.Cos(theta)); } else { phi = 0; if (m31 == -1) { theta = Math.PI / 2; psi = phi + Math.Atan2(m12, m13); } else { theta = -Math.PI / 2; psi = -phi + Math.Atan2(-m12, -m13); } } // Output in degrees? //myAxisSystem.RotationAngles.X = psi * 180 / Math.PI; //myAxisSystem.RotationAngles.Y = theta * 180 / Math.PI; //myAxisSystem.RotationAngles.Z = phi * 180 / Math.PI; var myRotadAngles = new Point3D(); myRotadAngles.X = psi; myRotadAngles.Y = theta; myRotadAngles.Z = phi; return(myRotadAngles); }
public override void Calculate(List <Particle> p) { Point3d P0 = p[PIndex[0]].Position; Point3d P1 = p[PIndex[1]].Position; Point3d P2 = p[PIndex[2]].Position; Point3d P3 = p[PIndex[3]].Position; Vector3d V01 = P1 - P0; Vector3d V02 = P2 - P0; Vector3d V03 = P3 - P0; Vector3d V21 = P1 - P2; Vector3d V31 = P1 - P3; double L01 = V01.Length; double invL01 = 1.0 / L01; double H0 = (V02 - V02 * invL01 * invL01 * V01 * V01).Length; double H1 = (V03 - V03 * invL01 * invL01 * V01 * V01).Length; double H = 0.5 / (H0 + H1); double Dot0201 = V02 * V01; double Dot0301 = V03 * V01; double Dot2101 = V21 * V01; double Dot3101 = V31 * V01; Vector3d Cross0 = Vector3d.CrossProduct(V02, V01); Vector3d Cross1 = Vector3d.CrossProduct(V01, V03); double CurrentAngle = Vector3d.VectorAngle(Cross0, Cross1, new Plane(P0, V01)); if (CurrentAngle > Math.PI) { CurrentAngle = CurrentAngle - 2 * Math.PI; } double AngleError = CurrentAngle - RestAngle; double OverFold = Math.Abs(AngleError) - PlasticLimit; // the amount of folding beyond the elastic/plastic threshold if (OverFold > 0) { if (AngleError > 0) { RestAngle += OverFold; AngleError -= OverFold; } else { RestAngle -= OverFold; AngleError += OverFold; } } double InvL = 1.0 / Cross0.Length; double Cot0u = Dot0201 * InvL; double Cot0v = Dot2101 * InvL; InvL = 1.0 / Cross1.Length; double Cot1u = Dot0301 * InvL; double Cot1v = Dot3101 * InvL; double D = AngleError * H * 0.5; Vector3d A = Cross0 * D; Move[0] = Cot0v * A; Move[1] = Cot0u * A; Move[2] = -(Cot0v + Cot0u) * A; A = Cross1 * D; Move[0] += Cot1v * A; Move[1] += Cot1u * A; Move[3] = -(Cot1v + Cot1u) * A; }
addUCS(Point3d pnt3dOrigin, Point3d pnt3dXaxis, Point3d pnt3dYaxis, string nameUCS) { Matrix3d newMatrix = new Matrix3d(); try { using (Transaction tr = BaseObjs.startTransactionDb()) { // Open the UCS table for read UcsTable ucsT = tr.GetObject(BaseObjs._db.UcsTableId, OpenMode.ForRead) as UcsTable; UcsTableRecord ucstr; Vector3d vector3dXaxis = new Vector3d(pnt3dXaxis.X - pnt3dOrigin.X, pnt3dXaxis.Y - pnt3dOrigin.Y, pnt3dXaxis.Z - pnt3dOrigin.Z); Vector3d vector3dYaxis = new Vector3d(pnt3dYaxis.X - pnt3dOrigin.X, pnt3dYaxis.Y - pnt3dOrigin.Y, pnt3dYaxis.Z - pnt3dOrigin.Z); Vector3d vector3dZ = vector3dXaxis.CrossProduct(vector3dYaxis); Vector3d vector3dY = vector3dZ.CrossProduct(vector3dXaxis); Vector3d vector3dPerpY = new Vector3d(vector3dY.X + pnt3dOrigin.X, vector3dY.Y + pnt3dOrigin.Y, vector3dY.Z + pnt3dOrigin.Z); // Check to see if the nameUCS UCS table record exists if (ucsT.Has(nameUCS) == false) { ucstr = new UcsTableRecord(); ucstr.Name = nameUCS; // Open the UCSTable for write ucsT.UpgradeOpen(); // Add the new UCS table record ucsT.Add(ucstr); tr.AddNewlyCreatedDBObject(ucstr, true); } else { ucstr = (UcsTableRecord)tr.GetObject(ucsT[nameUCS], OpenMode.ForWrite); } ucstr.Origin = pnt3dOrigin; ucstr.XAxis = vector3dXaxis; ucstr.YAxis = vector3dPerpY; // Open the active viewport ViewportTableRecord vptr; vptr = (ViewportTableRecord)tr.GetObject(BaseObjs._editor.ActiveViewportId, OpenMode.ForWrite); // Display the UCS Icon at the origin of the current viewport vptr.IconAtOrigin = true; vptr.IconEnabled = true; // Set the UCS current vptr.SetUcs(ucstr.ObjectId); BaseObjs._editor.UpdateTiledViewportsFromDatabase(); newMatrix = Matrix3d.AlignCoordinateSystem(Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, vptr.Ucs.Origin, vptr.Ucs.Xaxis, vptr.Ucs.Yaxis, vptr.Ucs.Zaxis); tr.Commit(); } } catch (System.Exception ex) { BaseObjs.writeDebug(ex.Message + " UCsys.cs: line: 149"); } return(newMatrix); }
public override bool Construct(bool append = false) { if (!append) { foreach (var part in Parts) { part.Geometry.Clear(); } } //var breps = new DataTree<Brep>(); var obeam = (Over.Element as BeamElement).Beam; var ubeam = (Under.Element as BeamElement).Beam; var oPlane = obeam.GetPlane(Over.Parameter); var uPlane = ubeam.GetPlane(Under.Parameter); Transform xform = Transform.PlaneToPlane(Plane.WorldXY, oPlane); double added = 10.0; double height = 0.0; var plane = new Plane((oPlane.Origin + uPlane.Origin) / 2, Vector3d.CrossProduct(oPlane.ZAxis, uPlane.ZAxis)); // Create beam side planes var planes = new Plane[4]; planes[0] = new Plane(oPlane.Origin + oPlane.XAxis * obeam.Width * 0.5, oPlane.ZAxis, oPlane.YAxis); planes[1] = new Plane(oPlane.Origin - oPlane.XAxis * obeam.Width * 0.5, -oPlane.ZAxis, oPlane.YAxis); planes[2] = new Plane(uPlane.Origin + uPlane.XAxis * ubeam.Width * 0.5, uPlane.ZAxis, uPlane.YAxis); planes[3] = new Plane(uPlane.Origin - uPlane.XAxis * ubeam.Width * 0.5, -uPlane.ZAxis, uPlane.YAxis); var planesOffset = planes.Select(x => new Plane(x.Origin + x.ZAxis * added, x.XAxis, x.YAxis)).ToArray(); var points = new Point3d[4]; Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(plane, planes[0], planes[2], out points[0]); Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(plane, planes[0], planes[3], out points[1]); Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(plane, planes[1], planes[2], out points[2]); Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(plane, planes[1], planes[3], out points[3]); // Create over cutter var oSrf = new Brep[3]; height = obeam.Height * 0.5 + added; var oPoints = new Point3d[] { points[0] - oPlane.ZAxis * added, points[1] + oPlane.ZAxis * added, points[2] - oPlane.ZAxis * added, points[3] + oPlane.ZAxis * added }; oSrf[0] = Brep.CreateFromCornerPoints(oPoints[0], oPoints[1], oPoints[2], oPoints[3], 0.01); oSrf[1] = Brep.CreateFromCornerPoints(oPoints[0], oPoints[1], oPoints[1] + plane.ZAxis * height, oPoints[0] + plane.ZAxis * height, 0.01); oSrf[2] = Brep.CreateFromCornerPoints(oPoints[2], oPoints[3], oPoints[3] + plane.ZAxis * height, oPoints[2] + plane.ZAxis * height, 0.01); var oJoined = Brep.JoinBreps(oSrf, 0.1); if (oJoined == null) { oJoined = oSrf; } Under.Geometry.AddRange(oJoined); // Create under cutter var uSrf = new Brep[3]; height = ubeam.Height * 0.5 + added; var uPoints = new Point3d[] { points[0] + uPlane.ZAxis * added, points[1] + uPlane.ZAxis * added, points[2] - uPlane.ZAxis * added, points[3] - uPlane.ZAxis * added }; uSrf[0] = Brep.CreateFromCornerPoints(uPoints[0], uPoints[1], uPoints[2], uPoints[3], 0.01); uSrf[1] = Brep.CreateFromCornerPoints(uPoints[0], uPoints[2], uPoints[2] - plane.ZAxis * height, uPoints[0] - plane.ZAxis * height, 0.01); uSrf[2] = Brep.CreateFromCornerPoints(uPoints[1], uPoints[3], uPoints[3] - plane.ZAxis * height, uPoints[1] - plane.ZAxis * height, 0.01); var uJoined = Brep.JoinBreps(uSrf, 0.1); if (uJoined == null) { uJoined = uSrf; } Over.Geometry.AddRange(uJoined); return(true); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { //---- Declareing --------------------------------------------------------------------------- GH_Structure <GH_Brep> AllStripes; DA.GetDataTree("Triloop Stipes", out AllStripes); GH_Structure <GH_Point> AllPoints; DA.GetDataTree("Points", out AllPoints); bool Reorient = false; DA.GetData <bool>("Merge Stripes", ref Reorient); bool Switch = false; DA.GetData <bool>("Switch", ref Switch); int Seam = 0; DA.GetData <int>("Seam", ref Seam); DataTree <Brep> AllUnrolledBreps = new DataTree <Brep>(); DataTree <Brep> ForReorientBreps = new DataTree <Brep>(); DataTree <Plane> AllOrientPlanes = new DataTree <Plane>(); DataTree <Curve> AllSharedCurves = new DataTree <Curve>(); DataTree <Point3d> AllUnrolledPoints = new DataTree <Point3d>(); //---- End Declareing ----------------------------------------------------------------------- //---- Functions ---------------------------------------------------------------------------- #region Unroll for (int i = 0; i < AllStripes.Branches.Count; i++) { GH_Path pth = new GH_Path(i); GH_Path originalPath = AllStripes.Paths[i]; int stripecounter = 0; foreach (GH_Brep gbrep in AllStripes[i]) { Unroller unroll = new Unroller(gbrep.Value); // Add points to unroll with if (AllPoints.Branches.Count != 0) { foreach (GH_Point pt in AllPoints[i]) { unroll.AddFollowingGeometry(pt.Value); } } unroll.ExplodeOutput = false; Curve[] curves; Point3d[] unrolledPoints; TextDot[] dots; Brep[] unrolledBreps = unroll.PerformUnroll(out curves, out unrolledPoints, out dots); if (Reorient == false) { foreach (Brep b in unrolledBreps) { AllUnrolledBreps.Add(b, originalPath); } foreach (Point3d p in unrolledPoints) { AllUnrolledPoints.Add(p, originalPath); } } else { foreach (Brep b in unrolledBreps) { AllUnrolledBreps.Add(b, pth.AppendElement(stripecounter)); } } // For reorientation if (Reorient == true) { ForReorientBreps.Add(unrolledBreps[Seam], pth); } stripecounter++; } } #endregion unroll if (Reorient == true) { //ForReorientBreps.Branch(0)[0].Curves3D[0].PointAtEnd; for (int i = 0; i < ForReorientBreps.BranchCount; i++) { GH_Path pth = new GH_Path(i); foreach (Curve crv0 in ForReorientBreps.Branch(i)[0].Curves3D) { foreach (Curve crv1 in ForReorientBreps.Branch(i)[1].Curves3D) { double l0 = crv0.GetLength(); double l1 = crv1.GetLength(); if (Math.Abs(l0 - l1) < 0.00001) { // orient crv0 Plane origin0 = new Plane(new Point3d(0, 0, 0), new Vector3d(1, 0, 0), new Vector3d(0, 1, 0)); Plane target0 = new Plane(origin0); AllOrientPlanes.Add(origin0, pth.AppendElement(0)); AllOrientPlanes.Add(target0, pth.AppendElement(0)); // orient crv1 Vector3d vect0 = crv1.TangentAtStart; Vector3d vect1 = Vector3d.CrossProduct(vect0, new Vector3d(0.0, 0.0, 1.0)); Plane origin1 = new Plane(crv1.PointAtStart, vect0, vect1); Vector3d vect2 = new Vector3d(); Vector3d vect3 = new Vector3d(); Plane target1 = new Plane(); if (Switch == true) { vect2 = crv0.TangentAtStart; vect3 = Vector3d.CrossProduct(vect2, new Vector3d(0.0, 0.0, 1.0)); target1 = new Plane(crv0.PointAtStart, vect2, vect3); } else { vect2 = crv0.TangentAtStart; vect3 = Vector3d.CrossProduct(-vect2, new Vector3d(0.0, 0.0, 1.0)); target1 = new Plane(crv0.PointAtEnd, -vect2, vect3); } AllOrientPlanes.Add(origin1, pth.AppendElement(1)); AllOrientPlanes.Add(target1, pth.AppendElement(1)); // shared curve of stripe0 and stripe 1 AllSharedCurves.Add(crv0, pth.AppendElement(0)); AllSharedCurves.Add(crv1, pth.AppendElement(0)); } } // orient crv2 foreach (Curve crv2 in ForReorientBreps.Branch(i)[2].Curves3D) { double l0 = crv0.GetLength(); double l1 = crv2.GetLength(); if (Math.Abs(l0 - l1) < 0.00001) { Vector3d vect0 = crv2.TangentAtStart; Vector3d vect1 = Vector3d.CrossProduct(vect0, new Vector3d(0.0, 0.0, 1.0)); Plane origin2 = new Plane(crv2.PointAtStart, vect0, vect1); Vector3d vect2 = new Vector3d(); Vector3d vect3 = new Vector3d(); Plane target2 = new Plane(); if (Switch == true) { vect2 = crv0.TangentAtStart; vect3 = Vector3d.CrossProduct(vect2, new Vector3d(0.0, 0.0, 1.0)); target2 = new Plane(crv0.PointAtStart, vect2, vect3); } else { vect2 = crv0.TangentAtStart; vect3 = Vector3d.CrossProduct(-vect2, new Vector3d(0.0, 0.0, 1.0)); target2 = new Plane(crv0.PointAtEnd, -vect2, vect3); } AllOrientPlanes.Add(origin2, pth.AppendElement(2)); AllOrientPlanes.Add(target2, pth.AppendElement(2)); // shared curve of stripe0 and stripe 2 AllSharedCurves.Add(crv2, pth.AppendElement(2)); AllSharedCurves.Add(crv0, pth.AppendElement(2)); } } } // find the shared curve oft stripe 1 and stripe 2 foreach (Curve crv1 in ForReorientBreps.Branch(i)[1].Curves3D) { foreach (Curve crv2 in ForReorientBreps.Branch(i)[2].Curves3D) { double l1 = crv1.GetLength(); double l2 = crv2.GetLength(); // shared curve of stripe1 and stripe 2 if (Math.Abs(l1 - l2) < 0.00001) { AllSharedCurves.Add(crv1, pth.AppendElement(1)); AllSharedCurves.Add(crv2, pth.AppendElement(1)); } } } } } //---- End Functions -------------------------------------------------------------------------- //----Set Output------------------------------------------------------------------------------- DA.SetDataTree(0, AllUnrolledBreps); DA.SetDataTree(1, AllOrientPlanes); DA.SetDataTree(2, AllSharedCurves); DA.SetDataTree(3, AllUnrolledPoints); //----End Set Output--------------------------------------------------------------------------- }
public override void Calculate(List <KangarooSolver.Particle> p) { //Lists of vertex normals and areas Vector3d[] normals = new Vector3d[pMesh.Vertices.Count]; double[] vertexAreas = new double[pMesh.Vertices.Count]; for (int j = 0; j < pMesh.Vertices.Count; j++) { normals[j] = new Vector3d(0, 0, 0); vertexAreas[j] = 0.0; } vol1 = 0.0; //Run through all mesh faces to calculate vertex normals, areas and current volume for (int i = 0; i < pMesh.Faces.Count; i++) { //Get face vertices int[] faceVertices = pMesh.Faces.GetFaceVertices(i); Point3d PA = p[PIndex[faceVertices[0]]].Position; Point3d PB = p[PIndex[faceVertices[1]]].Position; Point3d PC = p[PIndex[faceVertices[2]]].Position; Vector3d AB = PB - PA; Vector3d BC = PC - PB; Vector3d CA = PA - PC; Vector3d normal = Vector3d.CrossProduct(AB, BC); double nodalArea = normal.Length / 6.0; normal.Unitize(); normals[faceVertices[0]] += normal; normals[faceVertices[1]] += normal; normals[faceVertices[2]] += normal; vertexAreas[faceVertices[0]] += nodalArea; vertexAreas[faceVertices[1]] += nodalArea; vertexAreas[faceVertices[2]] += nodalArea; //Current volume Point3d PD = new Point3d(0, 0, 0); Vector3d AD = PD - PA; Vector3d cross = Vector3d.CrossProduct(AB, CA); double dot = Vector3d.Multiply(cross, AD); vol1 += (1.0 / 6.0) * dot; } //constant molecules -> pressure adjusts if (opt == false) { pres1 = (mol0 * gasConst * temp) / vol1; } //constant pressure -> molecules adjust else { mol1 = (pres0 * vol1) / (gasConst * temp); } //Calculate pressure vector acting in each vertex in [N] for (int k = 0; k < pMesh.Vertices.Count; k++) { Vector3d n = new Vector3d(normals[k]); n.Unitize(); if (negativePres) { n.Reverse(); } Move[k] = pres1 * vertexAreas[k] * n; } }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Rhino.Geometry.Mesh M = null; if (!DA.GetData(0, ref M)) { return; } List <int> L = new List <int>(); if (!DA.GetDataList(1, L)) { return; } List <double> offset = new List <double>(); if (!DA.GetDataList(2, offset)) { return; } // Check that the mesh is valid, weld all edges, recalculate vertex normals if (!M.IsValid) { return; } /*M.Weld(Math.PI); // Not compatible with Rhino 4! * M.Compact(); * M.UnifyNormals(); * M.Flip(true, true, true);*/ M.Normals.ComputeNormals(); //M.Normals.UnitizeNormals(); int n = M.TopologyVertices.Count; int m = M.TopologyEdges.Count; List <Point3f[]> layers = new List <Point3f[]>(); List <string> bars = new List <string>(); // Add dummy zero offset offset.Insert(0, 0); // for each layer, add two center line "layers" // (note: the first layer of nodes will be "on" the surface of the mesh, otherwise remove "- 0.5 * offset[1]"!) for (int i = 1; i < offset.Count; i++) { Point3f[] l0 = new Point3f[n]; Point3f[] l1 = new Point3f[n]; for (int j = 0; j < n; j++) { int vertex = M.TopologyVertices.MeshVertexIndices(j)[0]; l0[j] = M.TopologyVertices[j] + (float)(2 * offset[i - 1] + 0.5 * offset[i] - 0.5 * offset[1]) * M.Normals[vertex]; l1[j] = M.TopologyVertices[j] + (float)(2 * offset[i - 1] + 1.5 * offset[i] - 0.5 * offset[1]) * M.Normals[vertex]; } layers.Add(l0); layers.Add(l1); } // Remove dummy zero offset offset.RemoveAt(0); // Bars - for each, list by 'line' and by start/end node indices (and calculate gamma angle) List <Line> lines = new List <Line>(); double[] gamma = new double[m]; for (int i = 0; i < m; i++) { Rhino.IndexPair se = M.TopologyEdges.GetTopologyVertices(i); // ------------------------------------------------------------------------------ // GAMMA Vector3d[] normals = new Vector3d[] { M.Normals[M.TopologyVertices.MeshVertexIndices(se.I)[0]], M.Normals[M.TopologyVertices.MeshVertexIndices(se.J)[0]] }; Vector3d avg = normals[0] + normals[1]; Plane vertical = new Plane(M.TopologyVertices[se.I], M.TopologyVertices[se.J], M.TopologyVertices[se.J] + Vector3f.ZAxis); Plane bar = new Plane(M.TopologyVertices[se.I], M.TopologyVertices[se.J], new Point3d(M.TopologyVertices[se.J]) + avg); gamma[i] = (180 * (Vector3d.VectorAngle(vertical.Normal, bar.Normal))) / Math.PI; gamma[i] *= Vector3d.CrossProduct(vertical.Normal, bar.Normal).IsParallelTo(M.TopologyVertices[se.J] - M.TopologyVertices[se.I]); // ------------------------------------------------------------------------------ if (L[i] == 0) { // WARP, add to layers 0, 2, 4, ... for (int j = 0; j < offset.Count; j++) { lines.Add(new Line(layers[2 * j][se.I], layers[2 * j][se.J])); bars.Add(string.Format("{0,6} {1,6}", (2 * j) * n + se.I + 1, (2 * j) * n + se.J + 1)); } } else { // WEFT, add to layers 1, 3, 5, ... for (int j = 0; j < offset.Count; j++) { lines.Add(new Line(layers[2 * j + 1][se.I], layers[2 * j + 1][se.J])); bars.Add(string.Format("{0,6} {1,6}", (2 * j + 1) * n + se.I + 1, (2 * j + 1) * n + se.J + 1)); } } } // Links for (int i = 0; i < M.TopologyVertices.Count; i++) { for (int j = 0; j < layers.Count - 1; j++) { lines.Add(new Line(layers[j][i], layers[j + 1][i])); bars.Add(string.Format("{0,6} {1,6}", (j) * n + i + 1, (j + 1) * n + i + 1)); } } // Nodes - list all by coordinates List <Point3f> nodes = new List <Point3f>(); for (int i = 0; i < layers.Count; i++) { nodes.AddRange(layers[i]); } DA.SetDataList(0, nodes); DA.SetDataList(1, bars); DA.SetDataList(2, gamma); DA.SetDataList(3, lines); }
public static Vector3d[] LaplacianSmooth(PlanktonMesh P, int W, double Strength) { int VertCount = P.Vertices.Count; Vector3d[] Smooth = new Vector3d[VertCount]; for (int i = 0; i < VertCount; i++) { if ((P.Vertices[i].IsUnused == false) && (P.Vertices.IsBoundary(i) == false)) { int[] Neighbours = P.Vertices.GetVertexNeighbours(i); Point3d Vertex = P.Vertices[i].ToPoint3d(); Point3d Centroid = new Point3d(); if (W == 0) { for (int j = 0; j < Neighbours.Length; j++) { Centroid = Centroid + P.Vertices[Neighbours[j]].ToPoint3d(); } Smooth[i] = ((Centroid * (1.0 / P.Vertices.GetValence(i))) - Vertex) * Strength; } if (W == 1) { //get the radial vectors of the 1-ring //get the vectors around the 1-ring //get the cotangent weights for each edge int valence = Neighbours.Length; Point3d[] NeighbourPts = new Point3d[valence]; Vector3d[] Radial = new Vector3d[valence]; Vector3d[] Around = new Vector3d[valence]; double[] CotWeight = new double[valence]; double WeightSum = 0; for (int j = 0; j < valence; j++) { NeighbourPts[j] = P.Vertices[Neighbours[j]].ToPoint3d(); Radial[j] = NeighbourPts[j] - Vertex; } for (int j = 0; j < valence; j++) { Around[j] = NeighbourPts[(j + 1) % valence] - NeighbourPts[j]; } for (int j = 0; j < Neighbours.Length; j++) { //get the cotangent weights int previous = (j + valence - 1) % valence; Vector3d Cross1 = Vector3d.CrossProduct(Radial[previous], Around[previous]); double Cross1Length = Cross1.Length; double Dot1 = Radial[previous] * Around[previous]; int next = (j + 1) % valence; Vector3d Cross2 = Vector3d.CrossProduct(Radial[next], Around[j]); double Cross2Length = Cross2.Length; double Dot2 = Radial[next] * Around[j]; CotWeight[j] = Math.Abs(Dot1 / Cross1Length) + Math.Abs(Dot2 / Cross2Length); WeightSum += CotWeight[j]; } double InvWeightSum = 1.0 / WeightSum; Vector3d ThisSmooth = new Vector3d(); for (int j = 0; j < Neighbours.Length; j++) { ThisSmooth = ThisSmooth + Radial[j] * CotWeight[j]; } Smooth[i] = ThisSmooth * InvWeightSum * Strength; } } } return(Smooth); }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = new Mesh(); DA.GetData(0, ref mesh); double size = 10; DA.GetData(1, ref size); double textScale = 0.75; DA.GetData(2, ref textScale); int iteration = DA.Iteration; bbox.Union(mesh.GetBoundingBox(false)); int[][] tv = mesh.GetNGonsTopoBoundaries(); int[][] fe = mesh.GetNGonFacesEdges(tv); var l = mesh.GetNGonFacesEdgesLines(fe); DataTree <int> dt2 = new DataTree <int>(); HashSet <int> allE = mesh.GetAllNGonEdges(tv); int[] allEArray = allE.ToArray(); int[][] ef = mesh.GetNgonsConnectedToNGonsEdges(allE, true); for (int i = 0; i < mesh.Ngons.Count; i++) { for (int j = 0; j < fe[i].Length; j++) { int elocal = Array.IndexOf(allEArray, fe[i][j]); int neiF = (ef[elocal][0] == i) ? ef[elocal][1] : ef[elocal][0]; dt2.Add(neiF, new Grasshopper.Kernel.Data.GH_Path(i, DA.Iteration)); } } List <Line> ld = new List <Line>(); foreach (var ll in l) { ld.AddRange(ll); } //this.PreparePreview(mesh, DA.Iteration, null, false,null,ld); Plane[] planes = mesh.GetNgonPlanes(); for (int i = 0; i < planes.Length; i++) { if (faces) { this.texts.Add(new Rhino.Display.Text3d("F" + i.ToString(), planes[i], size)); } } for (int i = 0; i < planes.Length; i++) { for (int j = 0; j < fe[i].Length; j++) { Point3d p = l[i][j].PointAt(0.5); p.Transform(Rhino.Geometry.Transform.Scale(planes[i].Origin, textScale)); Plane edgePlane = new Plane(p, l[i][j].Direction, Vector3d.CrossProduct(planes[i].ZAxis, l[i][j].Direction)); if (edgesE) { this.texts.Add(new Rhino.Display.Text3d("E" + fe[i][j].ToString(), edgePlane, size * 0.75)); } if (edgesF) { this.texts.Add(new Rhino.Display.Text3d("F" + dt2.Branch(i)[j].ToString(), edgePlane, size * 0.75)); } } } DA.SetDataTree(0, GrasshopperUtil.JaggedArraysToTree(l, iteration)); DA.SetDataTree(1, GrasshopperUtil.JaggedArraysToTree(fe, iteration)); DA.SetDataTree(2, dt2); }
/// <summary> /// Gets the geodesic curve on mesh. /// </summary> /// <returns>The geodesic curve on mesh.</returns> /// <param name="mesh">Mesh.</param> /// <param name="startPoint">Start point.</param> /// <param name="startDirection">Start direction.</param> /// <param name="iter">Iter.</param> public static Polyline getGeodesicCurveOnMesh(Mesh mesh, Point3d startPoint, Vector3d startDirection, int iter) { double tol = 0.001; // Get meshPoint from start location mesh.UnifyNormals(); mesh.Normals.ComputeNormals(); MeshPoint mP = mesh.ClosestMeshPoint(startPoint, 0.0); int thisFaceIndex = mP.FaceIndex; //Debug.WriteLine("Face index:{0}", mP.FaceIndex); int thisEdgeIndex = -1; // Project direction to be tangent to the mesh. Vector3d norm = mesh.FaceNormals[thisFaceIndex]; Vector3d crossP = Vector3d.CrossProduct(startDirection, norm); Vector3d correctedDir = Vector3d.CrossProduct(norm, crossP); correctedDir.Unitize(); // Empty lists for result values List <Point3d> geodesicPoints = new List <Point3d>(); List <Vector3d> geodesicVectors = new List <Vector3d>(); // Add initial values to the lists geodesicPoints.Add(startPoint); geodesicVectors.Add(correctedDir); int nextFaceIndex = -1; for (int i = 0; i < iter; i++) { //Debug.WriteLine("Iter {0}", i); if (nextFaceIndex == -2) { break; } // Get starting meshFace MeshFace thisFace = mesh.Faces[thisFaceIndex]; int[] faceEdges = mesh.TopologyEdges.GetEdgesForFace(thisFaceIndex); Plane directionPlane = new Plane(mP.Point, mesh.NormalAt(mP), correctedDir); foreach (int edgeIndex in faceEdges) { //Debug.WriteLine("new edge {0}", edgeIndex); if (edgeIndex == thisEdgeIndex) { continue; } Line edgeLine = mesh.TopologyEdges.EdgeLine(edgeIndex); double t; bool success = Rhino.Geometry.Intersect.Intersection.LinePlane(edgeLine, directionPlane, out t); if (success && t > 0 && t < 1) { //Debug.WriteLine("t: {0}, edge-t0: {1}, edge-t1:{2} ", t, edgeLine.ClosestParameter(edgeLine.From), edgeLine.ClosestParameter(edgeLine.To)); // Check if the the point is IN FRONT or BEHIND the current direction. Vector3d newV = new Vector3d(edgeLine.PointAt(t) - mP.Point); newV.Unitize(); double angle = Vector3d.VectorAngle(correctedDir, newV); //Debug.WriteLine("Vector angle: {0}", angle); // Only continue if angle is THE SAME (considered as a threshold for consistency) if (angle > 0.05) { continue; } //Debug.WriteLine("Continue with this point"); Point3d nextPoint = edgeLine.PointAt(t); int[] connectedFaces = mesh.TopologyEdges.GetConnectedFaces(edgeIndex); //Debug.WriteLine("ConnectedFaces count: {0}", connectedFaces.Length); if (connectedFaces.Length == 1) { nextFaceIndex = -2; geodesicPoints.Add(nextPoint); break; } foreach (int faceIndex in connectedFaces) { //Check which is NOT the current face if (faceIndex != thisFaceIndex) { nextFaceIndex = faceIndex; } } // If no adjacent face was found, the curve has reached the boundary. if (nextFaceIndex == -1) { break; } else { //Debug.WriteLine("Update data for next iter"); Vector3d faceNormal = mesh.FaceNormals[thisFaceIndex]; Vector3d nextFaceNormal = mesh.FaceNormals[nextFaceIndex]; Vector3d cP = Vector3d.CrossProduct(correctedDir, faceNormal); correctedDir = Vector3d.CrossProduct(nextFaceNormal, cP); correctedDir.Unitize(); mP = mesh.ClosestMeshPoint(nextPoint, tol); geodesicPoints.Add(mP.Point); //Add new point to list; geodesicVectors.Add(correctedDir); // Add corrected direction to list thisFaceIndex = nextFaceIndex; thisEdgeIndex = edgeIndex; break; } } else { //Debug.WriteLine("No intersection found"); } } } return(new Polyline(geodesicPoints)); }
protected override void SolveInstance(IGH_DataAccess DA) { PlanktonMesh P1 = null; if (!DA.GetData(0, ref P1)) { return; } List <double> RL = new List <double>(); if (!DA.GetDataList(1, RL)) { return; } bool D = false; if (!DA.GetData(2, ref D)) { return; } if (D) { P1 = P1.Dual(); } PlanktonMesh P2 = new PlanktonMesh(); int vcount = P1.Vertices.Count; List <Vector3d> Normals = new List <Vector3d>(); List <int> Outer = new List <int>(); List <int> Inner = new List <int>(); List <int> Elbow = new List <int>(); for (int i = 0; i < vcount; i++) { Point3d Vertex = P1.Vertices[i].ToPoint3d(); Vector3d Normal = new Vector3d(); double AvgAngle = 0; double R = 0; if (RL.Count == 1) { R = RL[0]; } else { R = RL[i]; } int[] OutEdges = P1.Vertices.GetHalfedges(i); int[] Neighbours = P1.Vertices.GetVertexNeighbours(i); Vector3d[] OutVectors = new Vector3d[Neighbours.Length]; int Valence = P1.Vertices.GetValence(i); for (int j = 0; j < Valence; j++) { Vector3d OutVector = P1.Vertices[Neighbours[j]].ToPoint3d() - Vertex; OutVector.Unitize(); OutVectors[j] = OutVector; } for (int j = 0; j < Valence; j++) { if (P1.Halfedges[OutEdges[(j + 1) % Valence]].AdjacentFace != -1) { Normal += (Vector3d.CrossProduct(OutVectors[(j + 1) % Valence], OutVectors[j])); } } Normal.Unitize(); Normals.Add(Normal); for (int j = 0; j < Valence; j++) { AvgAngle += Vector3d.VectorAngle(Normal, OutVectors[j]); } AvgAngle = AvgAngle * (1.0 / Valence); double Offset = R / (Math.Sin(AvgAngle)); Outer.Add(P2.Vertices.Add(Vertex + (Normal * Offset))); //this adds the actual point to the mesh, as well as its index to Outer Inner.Add(P2.Vertices.Add(Vertex - (Normal * Offset))); } for (int i = 0; i < P1.Halfedges.Count; i++) { //get the 3 points of the angle int Prev = P1.Halfedges[i].PrevHalfedge; int Next = P1.Halfedges[i].NextHalfedge; int PrevV = P1.Halfedges[Prev].StartVertex; int NextV = P1.Halfedges[Next].StartVertex; int ThisV = P1.Halfedges[i].StartVertex; double R = 0; if (RL.Count == 1) { R = RL[0]; } else { R = RL[ThisV]; } Point3d PrevPt = P1.Vertices[PrevV].ToPoint3d(); Point3d NextPt = P1.Vertices[NextV].ToPoint3d(); Point3d ThisPt = P1.Vertices[ThisV].ToPoint3d(); //construct the point at the inside of the 'elbow' Vector3d Arm1 = PrevPt - ThisPt; Vector3d Arm2 = NextPt - ThisPt; Arm1.Unitize(); Arm2.Unitize(); double alpha = Vector3d.VectorAngle(Arm1, Arm2); Point3d ThisElbow; Vector3d Bisect = new Vector3d(); if (P1.Halfedges[i].AdjacentFace == -1) { Bisect = Vector3d.CrossProduct(Normals[ThisV], -1.0 * Arm1) + Vector3d.CrossProduct(Normals[ThisV], Arm2); } else { Bisect = Arm1 + Arm2; } Bisect.Unitize(); ThisElbow = ThisPt + Bisect * (R / Math.Sin(alpha * 0.5)); Elbow.Add(P2.Vertices.Add(ThisElbow)); } for (int i = 0; i < P1.Halfedges.Count; i++) { int Next = P1.Halfedges[i].NextHalfedge; int NextV = P1.Halfedges[Next].StartVertex; int ThisV = P1.Halfedges[i].StartVertex; P2.Faces.AddFace(Outer[ThisV], Outer[NextV], Elbow[Next], Elbow[i]); P2.Faces.AddFace(Elbow[i], Elbow[Next], Inner[NextV], Inner[ThisV]); } Mesh OutputMesh = P2.ToRhinoMesh(); DA.SetData(0, OutputMesh); }
/// <summary> /// 폴리라인의 각 변마다 거리를 지정해 Offset 커브를 만들어줍니다. /// </summary> public static List <Curve> ImprovedOffset(Polyline bound, List <double> offsetDist) { Polyline ccwBound = AlignPolyline(bound); List <Point3d> trimmedOffsetPt = new List <Point3d>(); //set vectors List <Vector3d> alignVector = SegmentVector.GetAlign(ccwBound, true); List <Vector3d> perpVector = SegmentVector.GetPerpendicular(ccwBound, true); List <Point3d> boundVertex = GetVertex(ccwBound); int numSegment = alignVector.Count; int numVertex = boundVertex.Count; //offset and trim segments for (int i = 0; i < numSegment; i++) { double a = offsetDist[i]; double b = offsetDist[(i + 1) % offsetDist.Count]; double dotProduct = Vector3d.Multiply(alignVector[i], alignVector[(i + 1) % numSegment]); Vector3d crossProduct = Vector3d.CrossProduct(alignVector[i], alignVector[(i + 1) % numSegment]); double cos = Math.Abs(dotProduct / (alignVector[i].Length * alignVector[(i + 1) % numSegment].Length)); double sin = Math.Sqrt(1 - Math.Pow(cos, 2)); double decider1 = Vector3d.Multiply(Plane.WorldXY.ZAxis, crossProduct); double decider2 = Vector3d.Multiply(-alignVector[i], alignVector[(i + 1) % numSegment]); Point3d tempPt = new Point3d(); if (decider1 > 0.005) // concave { if (decider2 < 0) // blunt { tempPt = boundVertex[(i + 1) % numVertex] + perpVector[i] * a + alignVector[i] * ((a * cos - b) / sin); } else // acute (right angle included) { tempPt = boundVertex[(i + 1) % numVertex] + perpVector[i] * a + alignVector[i] * ((-a * cos - b) / sin); } } else if (decider1 < -0.005) // convex { if (decider2 < 0) //blunt { tempPt = boundVertex[(i + 1) % numVertex] + perpVector[i] * a + alignVector[i] * ((-a * cos + b) / sin); } else // acute (right angle included) { tempPt = boundVertex[(i + 1) % numVertex] + perpVector[i] * a + alignVector[i] * ((a * cos + b) / sin); } } else //straight & near straight { tempPt = boundVertex[(i + 1) % numVertex] + perpVector[i] * Math.Max(a, b); } trimmedOffsetPt.Add(tempPt); } trimmedOffsetPt.Add(trimmedOffsetPt[0]); Polyline offBound = new Polyline(trimmedOffsetPt); //remove loop //List<Curve> loopOut = RemoveLoop(offBound, ccwBound, 0.001); //return loopOut; List <Curve> debug = new List <Curve>(); debug.Add(offBound.ToNurbsCurve()); return(debug); }
/// <summary> /// Create a Glulam from arbitrary geometry and a guide curve. The curve describes the fibre direction of the Glulam. This will /// create a Glulam which completely envelops the input geometry and whose centreline is offset from the input guide curve, to /// preserve the desired fibre orientation. /// </summary> /// <param name="curve">Guide curve to direct the Glulam.</param> /// <param name="beam">Beam geometry as Mesh.</param> /// <param name="extra">Extra material tolerance to leave on Glulam (the width and height of the Glulam will be /// increased by this much).</param> /// <returns>A new Glulam which envelops the input beam geometry, plus an extra tolerance as defined above.</returns> static public Glulam CreateGlulamFromBeamGeometry(Curve curve, Mesh beam, out double true_width, out double true_height, out double true_length, double extra = 0.0) { double t, l; Plane cp = Plane.Unset; Plane cpp; Polyline ch; Mesh m = new Mesh(); List <Plane> frames = new List <Plane>(); double[] tt = curve.DivideByCount(20, true); if (curve.IsLinear()) { m = beam.DuplicateMesh(); curve.PerpendicularFrameAt(curve.Domain.Min, out cp); m.Transform(Rhino.Geometry.Transform.PlaneToPlane(cp, Plane.WorldXY)); m.Faces.Clear(); Plane twist = Plane.WorldXY; m = m.FitToAxes(Plane.WorldXY, out ch, ref twist); double angle = Vector3d.VectorAngle(Vector3d.XAxis, twist.XAxis); int sign = Math.Sign(twist.YAxis * Vector3d.XAxis); cp.Transform(Rhino.Geometry.Transform.Rotation(angle * sign, cp.ZAxis, cp.Origin)); frames.Add(cp); } else if (curve.TryGetPlane(out cpp, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance)) { for (int i = 0; i < tt.Length; ++i) { Vector3d xaxis = Vector3d.CrossProduct(cpp.ZAxis, curve.TangentAt(tt[i])); cp = new Plane(curve.PointAt(tt[i]), xaxis, cpp.ZAxis); frames.Add(cp); } for (int i = 0; i < beam.Vertices.Count; ++i) { Point3d p = new Point3d(beam.Vertices[i]); curve.ClosestPoint(p, out t); l = curve.GetLength(new Interval(curve.Domain.Min, t)); Vector3d xaxis = Vector3d.CrossProduct(cpp.ZAxis, curve.TangentAt(t)); cp = new Plane(curve.PointAt(t), xaxis, cpp.ZAxis); p.Transform(Rhino.Geometry.Transform.PlaneToPlane(cp, Plane.WorldXY)); p.Z = l; m.Vertices.Add(p); } } else { for (int i = 0; i < beam.Vertices.Count; ++i) { Point3d p = new Point3d(beam.Vertices[i]); curve.ClosestPoint(p, out t); l = curve.GetLength(new Interval(curve.Domain.Min, t)); curve.PerpendicularFrameAt(t, out cp); p.Transform(Rhino.Geometry.Transform.PlaneToPlane(cp, Plane.WorldXY)); p.Z = l; m.Vertices.Add(p); } Plane twist = Plane.WorldXY; m = m.FitToAxes(Plane.WorldXY, out ch, ref twist); double angle = Vector3d.VectorAngle(Vector3d.XAxis, twist.XAxis); int sign = Math.Sign(twist.YAxis * Vector3d.XAxis); for (int i = 0; i < tt.Length; ++i) { curve.PerpendicularFrameAt(tt[i], out cp); cp.Transform(Rhino.Geometry.Transform.Rotation(angle * sign, cp.ZAxis, cp.Origin)); frames.Add(cp); } } m.Faces.AddFaces(beam.Faces); m.FaceNormals.ComputeFaceNormals(); BoundingBox bb = m.GetBoundingBox(true); double offsetX = bb.Center.X; double offsetY = bb.Center.Y; Brep bb2 = bb.ToBrep(); bb2.Transform(Rhino.Geometry.Transform.PlaneToPlane(Plane.WorldXY, cp)); true_width = bb.Max.X - bb.Min.X + extra; true_height = bb.Max.Y - bb.Min.Y + extra; // Now we create the glulam... //tasTools.Lam.Glulam glulam = tasTools.Lam.Glulam.CreateGlulam(curve, frames.ToArray()); Beam temp_beam = new Beam(curve, null, frames.ToArray()); int samples = (int)(curve.GetLength() / GlulamData.DefaultSampleDistance); Curve new_curve = temp_beam.CreateOffsetCurve(offsetX, offsetY, samples, true); new_curve = new_curve.Extend(CurveEnd.Both, 5.0 + extra, CurveExtensionStyle.Smooth); GlulamData data = GlulamData.FromCurveLimits(new_curve, frames.ToArray()); if (new_curve.IsPlanar()) { data.LamHeight = Math.Ceiling(true_height); data.Lamellae = new Stick[(int)(Math.Ceiling(true_width / data.LamWidth)), 1]; } else if (new_curve.IsLinear()) { data.LamHeight = Math.Ceiling(true_height); data.LamWidth = Math.Ceiling(true_width); data.Lamellae = new Stick[1, 1]; } else { data.Lamellae = new Stick[(int)(Math.Ceiling(true_width / data.LamWidth)), (int)(Math.Ceiling(true_height / data.LamHeight))]; } Glulam glulam = tas.Lam.Glulam.CreateGlulam(new_curve, frames.ToArray(), data); /* * tt = glulam.Centreline.DivideByCount(100, true); * double maxK = 0.0; * * int index = 0; * Vector3d kvec = Vector3d.Unset; * Vector3d temp; * * for (int i = 0; i < tt.Length; ++i) * { * temp = glulam.Centreline.CurvatureAt(tt[i]); * if (temp.Length > maxK) * { * index = i; * kvec = temp; * maxK = temp.Length; * } * } * Plane frame = glulam.GetPlane(tt[index]); * * double min_lam_width = 1.0; * double min_lam_height = 1.0; * double max_lam_width = (double)((int)Math.Ceiling(true_width / 10.0) * 10.0); * double max_lam_height = (double)((int)Math.Ceiling(true_height / 10.0) * 10.0); * * double lam_width = Math.Ceiling(Math.Min(1 / (Math.Abs(kvec * frame.XAxis) * 200), max_lam_width)); * double lam_height = Math.Ceiling(Math.Min(1 / (Math.Abs(kvec * frame.YAxis) * 200), max_lam_height)); * * if (lam_width == 0.0) lam_width = max_lam_width; * if (lam_height == 0.0) lam_height = max_lam_height; * * glulam.Data.LamHeight = lam_height; * glulam.Data.LamWidth = lam_width; * glulam.Data.NumHeight = (int)(Math.Ceiling(true_height / lam_height)); * glulam.Data.NumWidth = (int)(Math.Ceiling(true_width / lam_width)); * * //double new_lam_height, new_lam_width; * * if (glulam.Data.NumHeight * glulam.Data.LamHeight - true_height > 20.0) * glulam.Data.LamHeight = Math.Ceiling((true_height + 10.0) / glulam.Data.NumHeight); * if (glulam.Data.NumWidth * glulam.Data.LamWidth - true_width > 20.0) * glulam.Data.LamWidth = Math.Ceiling((true_width + 10.0) / glulam.Data.NumWidth); */ true_length = new_curve.GetLength(); return(glulam); }
private void btnAlign_Click(object sender, EventArgs e) { Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; using (EditorUserInteraction UI = ed.StartUserInteraction(this)) { PromptEntityOptions opts = new PromptEntityOptions("\nSelect entity: "); opts.AllowNone = false; opts.SetRejectMessage("\nSelect a LINE, ARC or POLYLINE entity."); opts.AddAllowedClass(typeof(Curve), false); PromptEntityResult per = ed.GetEntity(opts); if (per.Status == PromptStatus.OK) { Point3d pt = per.PickedPoint; ObjectId id = per.ObjectId; bool posUp = false; Vector3d dir = new Vector3d(), up = new Vector3d(), normal = new Vector3d(); Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr = db.TransactionManager.StartTransaction()) { try { RebarPos pos = (RebarPos)tr.GetObject(m_Pos, OpenMode.ForRead); Curve curve = (Curve)tr.GetObject(id, OpenMode.ForRead); pt = curve.GetClosestPointTo(pt, curve.GetPlane().Normal, false); dir = curve.GetFirstDerivative(pt); dir = dir * pos.DirectionVector.Length / dir.Length; normal = pos.NormalVector; normal = normal * pos.DirectionVector.Length / normal.Length; up = dir.CrossProduct(normal); up = up * pos.DirectionVector.Length / up.Length; posUp = (dir.DotProduct(pos.UpVector) > 0); } catch (System.Exception ex) { System.Windows.Forms.MessageBox.Show("Error: " + ex.Message, "RebarPos", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } } double offset = 0.0; double offset1 = -0.75, offset2 = 1.75; if (posUp) { AlignPos(pt + offset1 * up, dir, up, normal); offset = offset2; } else { AlignPos(pt + offset2 * up, dir, up, normal); offset = offset1; } PromptKeywordOptions kopts = new PromptKeywordOptions("\nDiğer tarafa yerleştirilsin mi? [Evet/Hayır] <Hayir>: ", "Yes No"); kopts.AllowNone = true; PromptResult kres = ed.GetKeywords(kopts); if (kres.Status == PromptStatus.None || kres.StringResult == "Yes") { AlignPos(pt + offset * up, dir, up, normal); ed.UpdateScreen(); } } } }