public void ReverseTransformPoint(RHVector3 v, RHVector3 outv) { Vector4 v4 = v.asVector4(); outv.x = Vector4.Dot(invTrans.Column0, v4); outv.y = Vector4.Dot(invTrans.Column1, v4); outv.z = Vector4.Dot(invTrans.Column2, v4); }
public void TransformPoint(RHVector3 v, out float x, out float y, out float z) { Vector4 v4 = v.asVector4(); x = Vector4.Dot(trans.Column0, v4); y = Vector4.Dot(trans.Column1, v4); z = Vector4.Dot(trans.Column2, v4); }
public void Center(float x, float y) { Land(); RHVector3 center = bbox.Center; Position.x += x - (float)center.x; Position.y += y - (float)center.y; }
private void includePoint(RHVector3 v) { float x, y, z; Vector4 v4 = v.asVector4(); x = Vector4.Dot(trans.Column0, v4); y = Vector4.Dot(trans.Column1, v4); z = Vector4.Dot(trans.Column2, v4); bbox.Add(new RHVector3(x, y, z)); }
public bool ContainsPoint(RHVector3 point) { if (minPoint == null) { return(false); } return(point.x >= minPoint.x && point.x <= maxPoint.x && point.y >= minPoint.y && point.y <= maxPoint.y && point.z >= minPoint.z && point.z <= maxPoint.z); }
//--- public void Add(RHVector3 point) { if (minPoint == null) { minPoint = new RHVector3(point); maxPoint = new RHVector3(point); } else { minPoint.StoreMinimum(point); maxPoint.StoreMaximum(point); } }
public override void Paint() { TopoModel model = ActiveModel; if (Visible) { if (false) //**Main.main.objectPlacement.checkCutFaces.Checked) { // int cutpos = Main.main.objectPlacement.cutPositionSlider.Value; if (ForceRefresh || ctrl.updateCuts || lastRendered != 1 || activeModel != activeSubmesh || lastShowEdges != SettingsProvider.Instance.ThreeDSettings.ShowEdges || lastSelected != Selected) { RHVector3 normpoint = ctrl.cutPos.Add(ctrl.cutDirection); RHVector3 point = new RHVector3(0, 0, 0); ReverseTransformPoint(ctrl.cutPos, point); ReverseTransformPoint(normpoint, normpoint); RHVector3 normal = normpoint.Subtract(point); submesh.Clear(); model.CutMesh(submesh, normal, point, outside ? Submesh.MESHCOLOR_OUTSIDE : Submesh.MESHCOLOR_FRONTBACK); submesh.selected = Selected; submesh.Compress(); lastShowEdges = SettingsProvider.Instance.ThreeDSettings.ShowEdges; lastSelected = Selected; activeSubmesh = activeModel; lastRendered = 1; } } else { if (ForceRefresh || ctrl.updateCuts || lastRendered != 0 || activeModel != activeSubmesh || lastShowEdges != SettingsProvider.Instance.ThreeDSettings.ShowEdges) { submesh.Clear(); submesh.defaultColor = ProjectManager.Instance.CurrentProject.projectSettings.PrinterSettings.Extruders[ExtruderNumber].ExtruderColor; model.FillMesh(submesh, outside ? Submesh.MESHCOLOR_OUTSIDE : Submesh.MESHCOLOR_FRONTBACK); submesh.selected = Selected; submesh.Compress(); lastShowEdges = SettingsProvider.Instance.ThreeDSettings.ShowEdges; lastSelected = Selected; activeSubmesh = activeModel; lastRendered = 0; } } // submesh.Draw(SettingsProvider.Instance.ThreeDSettings.drawMethod,ctrl.cam.EdgeTranslation()); submesh.Draw(2, ctrl.cam.EdgeTranslation()); } ForceRefresh = false; }
public TopoVertex[] getVertices() { TopoVertex[] vertices = new TopoVertex[8]; RHVector3 MAX = maxPoint; RHVector3 min = minPoint; vertices[0] = new TopoVertex(0, new RHVector3(min.x, min.y, min.z)); vertices[1] = new TopoVertex(1, new RHVector3(min.x, min.y, MAX.z)); vertices[2] = new TopoVertex(2, new RHVector3(min.x, MAX.y, min.z)); vertices[3] = new TopoVertex(3, new RHVector3(min.x, MAX.y, MAX.z)); vertices[4] = new TopoVertex(4, new RHVector3(MAX.x, min.y, min.z)); vertices[5] = new TopoVertex(5, new RHVector3(MAX.x, min.y, MAX.z)); vertices[6] = new TopoVertex(6, new RHVector3(MAX.x, MAX.y, min.z)); vertices[7] = new TopoVertex(7, new RHVector3(MAX.x, MAX.y, MAX.z)); return(vertices); }
public RHVector3 findNearest(double x, double y) { RHVector3 best = null; RHVector3 pos = new RHVector3(x, y, 0); double bestdist = 1e20; for (int i = 0; i < n; i++) { RHVector3 act = points[i]; double dist = act.Distance(pos); if (dist < bestdist) { best = act; bestdist = dist; } } return(best); }
private void Project(TopoVertex[] points, RHVector3 axis, out double min, out double max) { min = double.PositiveInfinity; max = double.NegativeInfinity; foreach (TopoVertex p in points) { //double val = axis.Dot(p); double val = axis.ScalarProduct(new RHVector3(p.pos.x, p.pos.y, p.pos.z)); if (val < min) { min = val; } if (val > max) { max = val; } } }
public override void Paint() { TopoModel model = ActiveModel; if (Main.main.objectPlacement.checkCutFaces.Checked) { int cutpos = Main.main.objectPlacement.cutPositionSlider.Value; if (ForceRefresh || Main.main.threedview.updateCuts || lastRendered != 1 || activeModel != activeSubmesh || lastShowEdges != Main.threeDSettings.ShowEdges || lastSelected != Selected) { RHVector3 normpoint = Main.main.threedview.cutPos.Add(Main.main.threedview.cutDirection); RHVector3 point = new RHVector3(0, 0, 0); ReverseTransformPoint(Main.main.threedview.cutPos, point); ReverseTransformPoint(normpoint, normpoint); RHVector3 normal = normpoint.Subtract(point); submesh.Clear(); model.CutMesh(submesh, normal, point, outside ? Submesh.MESHCOLOR_OUTSIDE : Submesh.MESHCOLOR_FRONTBACK); submesh.selected = Selected; submesh.Compress(); lastShowEdges = Main.threeDSettings.ShowEdges; lastSelected = Selected; activeSubmesh = activeModel; lastRendered = 1; } } else { if (ForceRefresh || Main.main.threedview.updateCuts || lastRendered != 0 || activeModel != activeSubmesh || lastShowEdges != Main.threeDSettings.ShowEdges) { submesh.Clear(); model.FillMesh(submesh, outside ? Submesh.MESHCOLOR_OUTSIDE : Submesh.MESHCOLOR_FRONTBACK); submesh.selected = Selected; submesh.Compress(); lastShowEdges = Main.threeDSettings.ShowEdges; lastSelected = Selected; activeSubmesh = activeModel; lastRendered = 0; } } submesh.Draw(Main.threeDSettings.drawMethod, Main.main.threedview.cam.EdgeTranslation()); ForceRefresh = false; }
private void buttonMeasureHeights_Click(object sender, EventArgs e) { minx = double.Parse(textXMin.Text, GCode.format); maxx = double.Parse(textXMax.Text, GCode.format); miny = double.Parse(textYMin.Text, GCode.format); maxy = double.Parse(textYMax.Text, GCode.format); nx = int.Parse(textXPoints.Text); ny = int.Parse(textYPoints.Text); dx = (maxx - minx) / (double)(nx - 1); dy = (maxy - miny) / (double)(ny - 1); n = nx * ny; points = new RHVector3[n]; int x, y; for (y = 0; y < ny; y++) { for (x = 0; x < nx; x++) { points[y * nx + x] = new RHVector3(minx + x * dx, miny + y * dy, 0); } } missing = n; Main.conn.eventResponse += Answer; buttonResultToClipboard.Enabled = false; for (int i = 0; i < n; i++) { RHVector3 act = points[i]; Main.conn.injectManualCommand("G1 X" + act.x.ToString("0.00", GCode.format) + " Y" + act.y.ToString("0.00", GCode.format) + " F" + Main.conn.travelFeedRate.ToString(GCode.format)); Main.conn.injectManualCommand("G30"); } /* string text = ""; * for (int i = 0; i < n; i++) * { * RHVector3 act = points[i]; * text += "G1 X" + act.x.ToString("0.00", GCode.format) + " Y" + act.y.ToString("0.00", GCode.format) + " F" + Main.conn.travelFeedRate.ToString(GCode.format)+"\n"; * text += "G30\n"; * } * Clipboard.SetText(text);*/ }
public void Answer(string text) { string sz = Main.conn.extract(text, "Z-probe:"); if (sz == null) { return; } string sx = Main.conn.extract(text, "X:"); string sy = Main.conn.extract(text, "Y:"); if (sx == null || sy == null) { return; } double x = double.Parse(sx, GCode.format); double y = double.Parse(sy, GCode.format); RHVector3 pnt = findNearest(x, y); pnt.z = double.Parse(sz, GCode.format); missing--; if (missing <= 0) { Main.conn.eventResponse -= Answer; zmin = 1e20; zmax = -1e20; zavg = 0; for (int i = 0; i < n; i++) { RHVector3 act = points[i]; zavg += act.z; zmin = Math.Min(zmin, act.z); zmax = Math.Max(zmax, act.z); } zavg /= (double)n; zcenter = (zmin + zmax) / 2.0; Main.main.Invoke(EnableButton); } }
private void buttonResultToClipboard_Click(object sender, EventArgs e) { StringBuilder s = new StringBuilder(); s.Append("X:\t"); for (int x = 0; x < nx; x++) { s.Append((minx + x * dx).ToString("0.00")); if (x < nx - 1) { s.Append("\t"); } else { s.AppendLine(); } } for (int y = ny - 1; y >= 0; y--) { s.Append("y:" + (miny + y * dy).ToString("0.00") + "\t"); for (int x = 0; x < nx; x++) { RHVector3 act = points[y * nx + x]; s.Append(act.z.ToString("0.00")); if (x < nx - 1) { s.Append("\t"); } else { s.AppendLine(); } } } Clipboard.SetText(s.ToString()); }
public void FitBoundingBox(RHBoundingBox box) { float bedRadius = (float)(1.5 * Math.Sqrt((ps.PrintAreaDepth * ps.PrintAreaDepth + ps.PrintAreaHeight * ps.PrintAreaHeight + ps.PrintAreaWidth * ps.PrintAreaWidth) * 0.25)); RHVector3 shift = new RHVector3(-ps.BedLeft - 0.5 * ps.PrintAreaWidth, -ps.BedFront - 0.5 * ps.PrintAreaDepth, -0.5 * ps.PrintAreaHeight); viewCenter = box.Center.asVector3(); distance = defaultDistance; int loops = 5; while (loops > 0) { loops--; angle = 15.0 * Math.PI / 180; double ratio = (double)control.gl.Width / (double)control.gl.Height; Vector3 camPos = CameraPosition; Matrix4 lookAt = Matrix4.LookAt(camPos.X, camPos.Y, camPos.Z, viewCenter.X, viewCenter.Y, viewCenter.Z, 0, 0, 1.0f); Matrix4 persp; Vector3 dir = new Vector3(); Vector3.Subtract(ref viewCenter, ref camPos, out dir); dir.Normalize(); float dist; Vector3.Dot(ref dir, ref camPos, out dist); dist = -dist; float nearDist = Math.Max(1, dist - bedRadius); float farDist = Math.Max(bedRadius * 2, dist + bedRadius); float nearHeight = 2.0f * (float)Math.Tan(angle) * dist; if (control.toolParallelProjection.Checked) { persp = Matrix4.CreateOrthographic(nearHeight * (float)ratio, nearHeight, nearDist, farDist); loops = 0; } else { persp = Matrix4.CreatePerspectiveFieldOfView((float)(angle * 2.0), (float)ratio, nearDist, farDist); } Matrix4 trans = Matrix4.Mult(lookAt, persp); RHVector3 min = new RHVector3(0, 0, 0); RHVector3 max = new RHVector3(0, 0, 0); Vector4 pos; RHBoundingBox bb = new RHBoundingBox(); pos = Vector4.Transform(box.minPoint.asVector4(), trans); bb.Add(new RHVector3(pos)); pos = Vector4.Transform(box.maxPoint.asVector4(), trans); bb.Add(new RHVector3(pos)); Vector4 pnt = new Vector4((float)box.xMin, (float)box.yMax, (float)box.zMin, 1); pos = Vector4.Transform(pnt, trans); bb.Add(new RHVector3(pos)); pnt = new Vector4((float)box.xMin, (float)box.yMax, (float)box.zMin, 1); pos = Vector4.Transform(pnt, trans); bb.Add(new RHVector3(pos)); pnt = new Vector4((float)box.xMax, (float)box.yMax, (float)box.zMin, 1); pos = Vector4.Transform(pnt, trans); bb.Add(new RHVector3(pos)); pnt = new Vector4((float)box.xMin, (float)box.yMax, (float)box.zMax, 1); pos = Vector4.Transform(pnt, trans); bb.Add(new RHVector3(pos)); pnt = new Vector4((float)box.xMin, (float)box.yMin, (float)box.zMax, 1); pos = Vector4.Transform(pnt, trans); bb.Add(new RHVector3(pos)); pnt = new Vector4((float)box.xMax, (float)box.yMin, (float)box.zMax, 1); pos = Vector4.Transform(pnt, trans); bb.Add(new RHVector3(pos)); double fac = Math.Max(Math.Abs(bb.xMin), Math.Abs(bb.xMax)); fac = Math.Max(fac, Math.Abs(bb.yMin)); fac = Math.Max(fac, Math.Abs(bb.yMax)); distance *= fac * 1.03; if (distance < 1) { angle = Math.Atan(distance * Math.Tan(15.0 * Math.PI / 180.0)); } } }
// Milton: Efficient AABB/triangle intersection algoirthm // from http://stackoverflow.com/questions/17458562/efficient-aabb-triangle-intersection-in-c-sharp public bool overlapTri(TopoTriangle triangle) { double triangleMin, triangleMax; double boxMin, boxMax; /*// Test the box normals (x-, y- and z-axes) * var boxNormals = new IVector[] { * new Vector(1,0,0), * new Vector(0,1,0), * new Vector(0,0,1) * };*/ RHVector3[] boxNormals = { new RHVector3(1, 0, 0), new RHVector3(0, 1, 0), new RHVector3(0, 0, 1) }; /* * for (int i = 0; i < 3; i++) * { * RHVector3 n = boxNormals[i]; * Project(triangle.vertices, boxNormals[i], out triangleMin, out triangleMax); * if (triangleMax < box.Start.Coords[i] || triangleMin > box.End.Coords[i]) * return false; // No intersection possible. * }*/ Project(triangle.vertices, boxNormals[0], out triangleMin, out triangleMax); if (triangleMax < minPoint.x || triangleMin > maxPoint.x) { return(false); } Project(triangle.vertices, boxNormals[1], out triangleMin, out triangleMax); if (triangleMax < minPoint.y || triangleMin > maxPoint.y) { return(false); } Project(triangle.vertices, boxNormals[2], out triangleMin, out triangleMax); if (triangleMax < minPoint.z || triangleMin > maxPoint.z) { return(false); } /*// Test the triangle normal * double triangleOffset = triangle.Normal.Dot(triangle.A); * Project(box.Vertices, triangle.Normal, out boxMin, out boxMax); * if (boxMax < triangleOffset || boxMin > triangleOffset) * return false; // No intersection possible.*/ double triangleOffset = triangle.normal.ScalarProduct(triangle.vertices[0].pos); Project(getVertices(), triangle.normal, out boxMin, out boxMax); if (boxMin < triangleOffset || boxMax > triangleOffset) { return(false); // No intersection possible. } /*// Test the nine edge cross-products * IVector[] triangleEdges = new IVector[] { * triangle.A.Minus(triangle.B), * triangle.B.Minus(triangle.C), * triangle.C.Minus(triangle.A) * }; */ RHVector3[] triangleEdges = { triangle.vertices[0].pos.Subtract(triangle.vertices[1].pos), triangle.vertices[1].pos.Subtract(triangle.vertices[2].pos), triangle.vertices[2].pos.Subtract(triangle.vertices[0].pos) }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { RHVector3 axis = triangleEdges[i].CrossProduct(boxNormals[j]); Project(getVertices(), axis, out boxMin, out boxMax); Project(triangle.vertices, axis, out triangleMin, out triangleMax); if (boxMax < triangleMin || boxMin > triangleMax) { return(false); // No intersection possible } } } return(true); }
public void Clear() { minPoint = maxPoint = null; }