/// <summary> /// Check that all values in other are within epsilon of the values in this /// </summary> /// <param name="other"></param> /// <param name="epsilon"></param> /// <returns></returns> public bool EpsilonEquals(NurbsSurfaceKnotList other, double epsilon) { if (null == other) { throw new ArgumentNullException("other"); } if (ReferenceEquals(this, other)) { return(true); } if (m_direction != other.m_direction) { return(false); } if (Count != other.Count) { return(false); } // check for equality of spans for (int i = 1; i < Count; ++i) { double myDelta = this[i] - this[i - 1]; double theirDelta = other[i] - other[i - 1]; if (!RhinoMath.EpsilonEquals(myDelta, theirDelta, epsilon)) { return(false); } } return(true); }
public bool EpsilonEquals(Quaternion other, double epsilon) { return(RhinoMath.EpsilonEquals(m_a, other.m_a, epsilon) && RhinoMath.EpsilonEquals(m_b, other.m_b, epsilon) && RhinoMath.EpsilonEquals(m_c, other.m_c, epsilon) && RhinoMath.EpsilonEquals(m_d, other.m_d, epsilon)); }
/// <summary> /// Check that all values in other are within epsilon of the values in this /// </summary> /// <param name="other"></param> /// <param name="epsilon"></param> /// <returns></returns> public bool EpsilonEquals(NurbsCurvePointList other, double epsilon) { if (null == other) { throw new ArgumentNullException("other"); } if (ReferenceEquals(this, other)) { return(true); } if (Count != other.Count) { return(false); } if (!RhinoMath.EpsilonEquals(ControlPolygonLength, other.ControlPolygonLength, epsilon)) { return(false); } for (int i = 0; i < Count; ++i) { ControlPoint mine = this[i]; ControlPoint theirs = other[i]; if (!mine.EpsilonEquals(theirs, epsilon)) { return(false); } } return(true); }
public bool EpsilonEquals(Sphere other, double epsilon) { return(m_plane.EpsilonEquals(other.m_plane, epsilon) && RhinoMath.EpsilonEquals(m_radius, other.m_radius, epsilon)); }
public bool EpsilonEquals(Arc other, double epsilon) { return(RhinoMath.EpsilonEquals(m_radius, other.m_radius, epsilon) && m_plane.EpsilonEquals(other.m_plane, epsilon) && m_angle.EpsilonEquals(other.m_angle, epsilon)); }
public bool EpsilonEquals(Cone other, double epsilon) { return(m_baseplane.EpsilonEquals(other.m_baseplane, epsilon) && RhinoMath.EpsilonEquals(m_height, other.m_height, epsilon) && RhinoMath.EpsilonEquals(m_radius, other.m_radius, epsilon)); }
public bool EpsilonEquals(Cylinder other, double epsilon) { return(m_basecircle.EpsilonEquals(other.m_basecircle, epsilon) && RhinoMath.EpsilonEquals(m_height1, other.m_height1, epsilon) && RhinoMath.EpsilonEquals(m_height2, other.m_height2, epsilon)); }
public static bool TryGetExtrusion(this Brep brep, out Extrusion extrusion) { if (brep.IsSurface) { return(brep.Faces[0].TryGetExtrusion(out extrusion)); } extrusion = null; if (brep.Faces.Count < 3) { return(false); } // Requiere manifold breps if (brep.SolidOrientation == BrepSolidOrientation.None || brep.SolidOrientation == BrepSolidOrientation.Unknown) { return(false); } // If brep has more that 3 faces we should check if there are faces with interior loops if (brep.Faces.Count > 3 && brep.Faces.Where(face => face.Loops.Count != 1).Any()) { return(false); } var candidateFaces = new List <int[]>(); // Array with just planar faces sorted by its area to search for similar faces var planarFaces = brep.Faces. Select(face => new PlanarBrepFace(face)). Where(face => face.Plane.IsValid). OrderByDescending(face => face.LoopArea). ToArray(); // A capped Extrusion converted to Brep has wall surfaces in face[0] to face[N-3], caps are face[N-2] and face[N-1] // I iterate in reverse order to be optimisitc, maybe brep comes from an Extrusion.ToBrep() call for (int f = planarFaces.Length - 1; f > 0; --f) { var planeF = planarFaces[f].Plane; var loopF = planarFaces[f].Loop; var centroidF = planarFaces[f].Centroid; // Check if they have same area. for (int g = f - 1; g >= 0 && RhinoMath.EpsilonEquals(planarFaces[f].LoopArea, planarFaces[g].LoopArea, RhinoMath.SqrtEpsilon); --g) { // Planes should be parallel or anti-parallel if (planeF.Normal.IsParallelTo(planarFaces[g].Plane.Normal, RhinoMath.DefaultAngleTolerance / 100.0) == 0) { continue; } // Here f, ang are perfect candidates to test adjacent faces for perpendicularity to them, // but we may try to quick reject some candidates if it's obvious that doesn't match // A "perfect" curve overlap match may be a test but is too much in this ocasion // We expect same NURBS structure, so point count should match if (loopF.Points.Count != planarFaces[g].Loop.Points.Count) { continue; } // Since we have computed the area the centroid comes for free. // Centroids should also match if (planeF.ClosestPoint(planarFaces[g].Centroid).DistanceToSquared(centroidF) > RhinoMath.SqrtEpsilon) { continue; } // Add result to candidates List reversing index order to keep extrusion creation direction // Breps that come from a Extrusion have the Cap[0] before Cap[1] candidateFaces.Add(new int[] { g, f }); } } // No twin faces found if (candidateFaces.Count == 0) { return(false); } // Candidates are in 'LoopArea' order, we will find here smaller profiles sooner // This is good for beam like objects, bad for slab like objects. // On box-like Breps the result could be ambigous for the user so, // to give him some control on the result, we will prioritize first and last faces no matter their area. // First and Last are "special" because if somebody observe an extrusion-like Brep and sees // it as an extrusion he tends to categorize faces in one of the following schemas: // { Cap[0], Wall[0] .. Wall[N], Cap[1] } // { Cap[0], Cap[1], Wall[0] .. Wall[N] } // { Wall[0] .. Wall[N], Cap[0], Cap[1] } // So if he is using the join command to create a Brep from surfaces at the model, // it's natural to start or end the selection with one of the extrusion caps. // On horizontal extrusions, slab-like Breps, the user use to observe the model from above, // so probably he will end with the bottom cap. // Also Last face is a Cap in Breps that come from Extrusion // If caps and walls are interleaved, smallest pair of faces will be used as caps, producing beam-like extrusions. // System.Linq.Enumerable.OrderBy performs a stable sort so only first and last face will be moved if found. foreach (var candidate in candidateFaces.OrderBy(pair => (planarFaces[pair[1]].Face.FaceIndex == brep.Faces.Count - 1) ? 0 : // Last, in case it comes from Extrusion (planarFaces[pair[0]].Face.FaceIndex == 0) ? 1 : // First, in case it comes from a JOIN command int.MaxValue)) // Others { var startFace = planarFaces[candidate[0]]; var endFace = planarFaces[candidate[1]]; // If any face, ignorig twins candidates, does not degenrate // to a curve when projected to 'planeF', then brep is not an extrusion if ( brep.Faces. Where(face => face.FaceIndex != startFace.Face.FaceIndex && face.FaceIndex != endFace.Face.FaceIndex). Select(face => startFace.ProjectionDegenartesToCurve(face.UnderlyingSurface())). Any(degenerateToCurve => degenerateToCurve == false) ) { return(false); } // We use the orginal OuterLoop as profile not the NURBS version of it // to keep the structure as much as possible var profile = startFace.Face.OuterLoop.To3dCurve(); double height = startFace.Face.OrientationIsReversed ? -startFace.Plane.DistanceTo(endFace.Plane.Origin) : +startFace.Plane.DistanceTo(endFace.Plane.Origin); extrusion = Extrusion.Create(profile, height, true); return(true); } return(false); }
public bool EpsilonEquals(Torus other, double epsilon) { return(m_majorCirclePlane.EpsilonEquals(other.m_majorCirclePlane, epsilon) && RhinoMath.EpsilonEquals(m_majorRadius, other.m_majorRadius, epsilon) && RhinoMath.EpsilonEquals(m_minorRadius, other.m_minorRadius, epsilon)); }
/// <summary> /// Check that all values in other are within epsilon of the values in this /// </summary> /// <param name="other"></param> /// <param name="epsilon"></param> /// <returns></returns> public bool EpsilonEquals(Ellipse other, double epsilon) { return(m_plane.EpsilonEquals(other.m_plane, epsilon) && RhinoMath.EpsilonEquals(m_radius1, other.m_radius1, epsilon) && RhinoMath.EpsilonEquals(m_radius2, other.m_radius2, epsilon)); }
/// <summary> /// Check that all values in other are withing epsilon of the values in this /// </summary> /// <param name="other"></param> /// <param name="epsilon"></param> /// <returns></returns> public bool EpsilonEquals(Vector3f other, float epsilon) { return(RhinoMath.EpsilonEquals(m_x, other.m_x, epsilon) && RhinoMath.EpsilonEquals(m_y, other.m_y, epsilon) && RhinoMath.EpsilonEquals(m_z, other.m_z, epsilon)); }
/// <summary> /// Check that all values in other are within epsilon of the values in this /// </summary> /// <param name="other"></param> /// <param name="epsilon"></param> /// <returns></returns> public bool EpsilonEquals(Point2f other, float epsilon) { return(RhinoMath.EpsilonEquals(m_x, other.m_x, epsilon) && RhinoMath.EpsilonEquals(m_y, other.m_y, epsilon)); }