public static Dictionary<int, DOEgbXMLBasics.EdgeFamily> FindMatchingEdges(List<SurfaceDefinitions> sblist) { Dictionary<int, DOEgbXMLBasics.EdgeFamily> uniqueedges = new Dictionary<int, DOEgbXMLBasics.EdgeFamily>(); int distinctedges = 0; foreach (SurfaceDefinitions sb in sblist) { int coordcount = sb.PlCoords.Count; for (int i = 0; i < coordcount; i++) { //initialize the edge being tested, the test edge DOEgbXMLBasics.EdgeFamily currentedge = new DOEgbXMLBasics.EdgeFamily(); currentedge.sbdec = sb.SurfaceId; currentedge.relatedEdges = new List<DOEgbXMLBasics.EdgeFamily>(); currentedge.startendpt = new List<Vector.MemorySafe_CartCoord>(); if (uniqueedges.Count == 0) { uniqueedges[distinctedges] = currentedge; //get the first coord in this set, and the coord next to it currentedge.startendpt.Add(sb.PlCoords[i]); currentedge.startendpt.Add(sb.PlCoords[i + 1]); distinctedges++; continue; } //most edges work the same, in terms of the start and end point, except for the last edge (the else case) if (i < coordcount - 1) { currentedge.startendpt.Add(sb.PlCoords[i]); currentedge.startendpt.Add(sb.PlCoords[i + 1]); } else { currentedge.startendpt.Add(sb.PlCoords[i]); currentedge.startendpt.Add(sb.PlCoords[0]); } //search through existing edges to try and find a perfect match int edgecount = 0; //keeps track of how many guest edges in the dictionary I've searched through foreach (KeyValuePair<int, DOEgbXMLBasics.EdgeFamily> kp in uniqueedges) { Vector.MemorySafe_CartCoord startpt = kp.Value.startendpt[0]; //looking for a perfect match of endpoints. If both match, then the //current edge is added to the current key/value pair's related edges. #region double diffx = Math.Abs(startpt.X - currentedge.startendpt[0].X); double diffy = Math.Abs(startpt.Y - currentedge.startendpt[0].Y); double diffz = Math.Abs(startpt.Z - currentedge.startendpt[0].Z); double tol = DOEgbXMLBasics.Tolerances.SurfacePLCoordTolerance; if (diffx <= tol && diffy <= tol && diffz <= tol) { //found at least one perfect coordinate match, try to match the second Vector.MemorySafe_CartCoord endpt = kp.Value.startendpt[1]; diffx = Math.Abs(endpt.X - currentedge.startendpt[1].X); diffy = Math.Abs(endpt.Y - currentedge.startendpt[1].Y); diffz = Math.Abs(endpt.Z - currentedge.startendpt[1].Z); if (diffx <= tol && diffy <= tol && diffz <= tol) { //both match, means the match is perfect, so add it to the related surfaces list kp.Value.relatedEdges.Add(currentedge); break; //key value pair break; } else { //the edge may be unique, though it could still have neighboring relationships //draw vector A double Ax = endpt.X - currentedge.startendpt[1].X; double Ay = endpt.Y - currentedge.startendpt[1].Y; double Az = endpt.Z - currentedge.startendpt[1].Z; Vector.MemorySafe_CartVect A = new Vector.MemorySafe_CartVect(Ax, Ay, Az); double Amag = Vector.VectorMagnitude(A); //take cross product to see if they are even in same plane double evX = endpt.X - startpt.X; double evY = endpt.Y - startpt.Y; double evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev = new Vector.MemorySafe_CartVect(evX, evY, evZ); double evmag = Vector.VectorMagnitude(ev); Vector.MemorySafe_CartVect cross = Vector.CrossProduct(A, ev); //TODO: do we need to make this a unit vector? double crossmag = Vector.VectorMagnitude(cross); if (Math.Abs(crossmag) < DOEgbXMLBasics.Tolerances.crossProductTolerance) { //then we are at least parallel or antiparallel, now see if the point resides on the edge or outside of it double Bx = startpt.X - currentedge.startendpt[1].X; double By = startpt.Y - currentedge.startendpt[1].Y; double Bz = startpt.Z - currentedge.startendpt[1].Z; Vector.MemorySafe_CartVect B = new Vector.MemorySafe_CartVect(Bx, By, Bz); double Bmag = Vector.VectorMagnitude(B); //check to see if the test edge is inside the guest edge if (Amag < evmag && Bmag < evmag) { //this means it lies on the plane at least, so it shares, but it is also still independent because a perfect match wasn't found kp.Value.relatedEdges.Add(currentedge); //accumulate its own relationships currentedge.relatedEdges.Add(kp.Value); edgecount++; continue; //continue looping through unique edges, if any } double edgeX = currentedge.startendpt[1].X - currentedge.startendpt[0].X; double edgeY = currentedge.startendpt[1].Y - currentedge.startendpt[0].Y; double edgeZ = currentedge.startendpt[1].Z - currentedge.startendpt[0].Z; Vector.MemorySafe_CartVect edgevec = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); double edgemag = Vector.VectorMagnitude(edgevec); double Cx = startpt.X - currentedge.startendpt[1].X; double Cy = startpt.Y - currentedge.startendpt[1].Y; double Cz = startpt.Z - currentedge.startendpt[1].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); double Dx = endpt.X - currentedge.startendpt[1].X; double Dy = endpt.Y - currentedge.startendpt[1].Y; double Dz = endpt.Z - currentedge.startendpt[1].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); if (Dmag < edgemag && Cmag <= edgemag) { //this means the test edge is longer than the guest edge, but they overlap kp.Value.relatedEdges.Add(currentedge); //the edge is still unique but accumulates a neighbor currentedge.relatedEdges.Add(kp.Value); edgecount++; continue; } } else { //this other point isn't relevant, and the edges don't coincide edgecount++; continue; } } } //end situation where first points match, next test if end points match #endregion else if (Math.Abs(startpt.X-currentedge.startendpt[1].X) < tol && Math.Abs(startpt.Y-currentedge.startendpt[1].Y)<tol && Math.Abs(startpt.Z-currentedge.startendpt[1].Z) < tol) { //found at least one perfect coordinate match, try to match the second Vector.MemorySafe_CartCoord endpt = kp.Value.startendpt[1]; diffx = Math.Abs(endpt.X - currentedge.startendpt[0].X); diffy = Math.Abs(endpt.Y - currentedge.startendpt[0].Y); diffz = Math.Abs(endpt.Z - currentedge.startendpt[0].Z); if (diffx < tol && diffy < tol && diffz < tol) { //both match, means the match is perfect, so add it to the related surfaces list kp.Value.relatedEdges.Add(currentedge); break; } else { //the edge may be unique, though it could still have neighboring relationships double Ax = endpt.X - currentedge.startendpt[0].X; double Ay = endpt.Y - currentedge.startendpt[0].Y; double Az = endpt.Z - currentedge.startendpt[0].Z; Vector.MemorySafe_CartVect A = new Vector.MemorySafe_CartVect(Ax, Ay, Az); double Amag = Vector.VectorMagnitude(A); //take cross product to see if they are even in same plane double evX = endpt.X - startpt.X; double evY = endpt.Y - startpt.Y; double evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev = new Vector.MemorySafe_CartVect(evX, evY, evZ); double evmag = Vector.VectorMagnitude(ev); Vector.MemorySafe_CartVect cross = Vector.CrossProduct(A, ev); //TODO: do we need to make this a unit vector? double crossmag = Vector.VectorMagnitude(cross); if (Math.Abs(crossmag) < DOEgbXMLBasics.Tolerances.crossProductTolerance) { //then we are at least parallel or antiparallel, now see if the point resides on the edge or outside of it double Bx = startpt.X - currentedge.startendpt[0].X; double By = startpt.Y - currentedge.startendpt[0].Y; double Bz = startpt.Z - currentedge.startendpt[0].Z; Vector.MemorySafe_CartVect B = new Vector.MemorySafe_CartVect(Bx, By, Bz); double Bmag = Vector.VectorMagnitude(B); //check to see if the test edge is inside the guest edge if (Amag < evmag && Bmag < evmag) { //this means it lies on the plane at least, so it shares, but it is also still independent because a perfect match wasn't found kp.Value.relatedEdges.Add(currentedge); //accumulate its own relationships currentedge.relatedEdges.Add(kp.Value); edgecount++; continue; } double edgeX = currentedge.startendpt[1].X - currentedge.startendpt[0].X; double edgeY = currentedge.startendpt[1].Y - currentedge.startendpt[0].Y; double edgeZ = currentedge.startendpt[1].Z - currentedge.startendpt[0].Z; Vector.MemorySafe_CartVect edgevec = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); double edgemag = Vector.VectorMagnitude(edgevec); double Cx = startpt.X - currentedge.startendpt[0].X; double Cy = startpt.Y - currentedge.startendpt[0].Y; double Cz = startpt.Z - currentedge.startendpt[0].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); double Dx = endpt.X - currentedge.startendpt[0].X; double Dy = endpt.Y - currentedge.startendpt[0].Y; double Dz = endpt.Z - currentedge.startendpt[0].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); if (Dmag < edgemag && Cmag <= edgemag) { //this means the test edge is longer than the guest edge, but they overlap kp.Value.relatedEdges.Add(currentedge); //the edge is still unique but accumulates a neighbor currentedge.relatedEdges.Add(kp.Value); edgecount++; continue; } } else { //this other point isn't relevant, and the edges don't coincide edgecount++; continue; } } } //neither points perfectly coincide, so we do an exhaustive overlap check. else #region { Vector.MemorySafe_CartCoord endpt = kp.Value.startendpt[1]; //are the two vectors even parallel? because if they are not, no need to get more complex double evX = endpt.X - startpt.X; double evY = endpt.Y - startpt.Y; double evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev = new Vector.MemorySafe_CartVect(evX, evY, evZ); double edgeX = currentedge.startendpt[1].X - currentedge.startendpt[0].X; double edgeY = currentedge.startendpt[1].Y - currentedge.startendpt[0].Y; double edgeZ = currentedge.startendpt[1].Z - currentedge.startendpt[0].Z; Vector.MemorySafe_CartVect edgev = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); if (Vector.VectorMagnitude(Vector.CrossProduct(ev, edgev)) > DOEgbXMLBasics.Tolerances.crossProductTolerance) { //they are not even parallel so move on edgecount++; continue; } //is one of the points inside of the edge? //test edge point 1 double Ax = endpt.X - currentedge.startendpt[0].X; double Ay = endpt.Y - currentedge.startendpt[0].Y; double Az = endpt.Z - currentedge.startendpt[0].Z; Vector.MemorySafe_CartVect A = new Vector.MemorySafe_CartVect(Ax, Ay, Az); double Amag = Vector.VectorMagnitude(A); //TODO: Remove //evX = endpt.X - startpt.X; //evY = endpt.Y - startpt.Y; //evZ = endpt.Z - startpt.Z; double uniqueMag = Vector.VectorMagnitude(ev); double Bx = startpt.X - currentedge.startendpt[0].X; double By = startpt.Y - currentedge.startendpt[0].Y; double Bz = startpt.Z - currentedge.startendpt[0].Z; Vector.MemorySafe_CartVect B = new Vector.MemorySafe_CartVect(Bx, By, Bz); double Bmag = Vector.VectorMagnitude(B); //check to see if the test edge's first point (index 0) is totally inside the guest edge // start x ---------- 0 --------------x end if (Amag + Bmag - uniqueMag < DOEgbXMLBasics.Tolerances.SurfacePLCoordTolerance) { //this is enough to prove that the two edges overlap, because we've already proven the two vectors are parallel //then it is inside as well, and test vector is engulfed by guest vector kp.Value.relatedEdges.Add(currentedge); //but the edge is still itself unique currentedge.relatedEdges.Add(kp.Value); edgecount++; continue; } //test edge point 2 double Cx = endpt.X - currentedge.startendpt[1].X; double Cy = endpt.Y - currentedge.startendpt[1].Y; double Cz = endpt.Z - currentedge.startendpt[1].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); //we are at least parallel, now to check for a real intersection double Dx = startpt.X - currentedge.startendpt[1].X; double Dy = startpt.Y - currentedge.startendpt[1].Y; double Dz = startpt.Z - currentedge.startendpt[1].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); // start x ---------- 1 --------------x end if (Cmag + Dmag - uniqueMag < DOEgbXMLBasics.Tolerances.SurfacePLCoordTolerance) { //this is enough to prove that the two edges overlap, because we've already proven the two vectors are parallel //then it is inside as well, and test vector is engulfed by guest vector kp.Value.relatedEdges.Add(currentedge); //but the edge is still itself unique currentedge.relatedEdges.Add(kp.Value); edgecount++; continue; } //now check to see if the two points overlap the edge and contain it completely, this is also a valid condition // 0 -------xstart------------------xend-------1 double edgeMag = Vector.VectorMagnitude(edgev); //use A,B if(Amag + Bmag - edgeMag < DOEgbXMLBasics.Tolerances.SurfacePLCoordTolerance) { //this is enough to prove that the two edges overlap, because we've already proven the two vectors are parallel //then it is inside as well, and test vector is engulfed by guest vector kp.Value.relatedEdges.Add(currentedge); //but the edge is still itself unique currentedge.relatedEdges.Add(kp.Value); edgecount++; continue; } //use C,D if (Cmag + Dmag - edgeMag < DOEgbXMLBasics.Tolerances.SurfacePLCoordTolerance) { //this is enough to prove that the two edges overlap, because we've already proven the two vectors are parallel //then it is inside as well, and test vector is engulfed by guest vector kp.Value.relatedEdges.Add(currentedge); //but the edge is still itself unique currentedge.relatedEdges.Add(kp.Value); edgecount++; continue; } //no matches were found. log the issue and increase the edgecount nonetheless //logger.Info("Edge (" + currentedge.startendpt[0].X + "," + currentedge.startendpt[0].Y + "," + currentedge.startendpt[0].Z + ")->(" + currentedge.startendpt[0].X + "," + currentedge.startendpt[0].Y + "," + currentedge.startendpt[0].Z + ") has not found a match."); edgecount++; } #endregion #region //{ // Vector.MemorySafe_CartCoord endpt = kp.Value.startendpt[1]; // //are the two vectors even parallel? because if they are not, no need to get more complex // double evX = endpt.X - startpt.X; // double evY = endpt.Y - startpt.Y; // double evZ = endpt.Z - startpt.Z; // Vector.MemorySafe_CartVect ev = new Vector.MemorySafe_CartVect(evX, evY, evZ); // double edgeX = currentedge.startendpt[1].X - currentedge.startendpt[0].X; // double edgeY = currentedge.startendpt[1].Y - currentedge.startendpt[0].Y; // double edgeZ = currentedge.startendpt[1].Z - currentedge.startendpt[0].Z; // Vector.MemorySafe_CartVect edgev = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); // //TODO: add tolerance // if (Vector.VectorMagnitude(Vector.CrossProduct(ev, edgev)) != 0) // { // //they are not even parallel so move on // edgecount++; // continue; // } // //try to determine if the two edges are parallel // //test edge point 1 // double Ax = endpt.X - currentedge.startendpt[0].X; // double Ay = endpt.Y - currentedge.startendpt[0].Y; // double Az = endpt.Z - currentedge.startendpt[0].Z; // Vector.MemorySafe_CartVect A = new Vector.MemorySafe_CartVect(Ax, Ay, Az); // double Amag = Vector.VectorMagnitude(A); // //take cross product to see if they are even in same plane // evX = endpt.X - startpt.X; // evY = endpt.Y - startpt.Y; // evZ = endpt.Z - startpt.Z; // Vector.MemorySafe_CartVect ev1 = new Vector.MemorySafe_CartVect(evX, evY, evZ); // double guestmag = Vector.VectorMagnitude(ev1); // Vector.MemorySafe_CartVect cross1 = Vector.CrossProduct(A, ev1); // double crossmag = Vector.VectorMagnitude(cross1); // //tolerance? // if (crossmag == 0) // { // //we are at least parallel, now to check for a real intersection // double Bx = startpt.X - currentedge.startendpt[0].X; // double By = startpt.Y - currentedge.startendpt[0].Y; // double Bz = startpt.Z - currentedge.startendpt[0].Z; // Vector.MemorySafe_CartVect B = new Vector.MemorySafe_CartVect(Bx, By, Bz); // double Bmag = Vector.VectorMagnitude(B); // //check to see if the test edge's first point (index 0) is totally inside the guest edge // if (Amag < guestmag && Bmag < guestmag) // #region // { // //the start point of the test edge is inside the guest edge // //test edge point 2 against guest edge point 2 // double Cx = endpt.X - currentedge.startendpt[1].X; // double Cy = endpt.Y - currentedge.startendpt[1].Y; // double Cz = endpt.Z - currentedge.startendpt[1].Z; // Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); // double Cmag = Vector.VectorMagnitude(C); // Vector.MemorySafe_CartVect cross2 = Vector.CrossProduct(C, ev); // crossmag = Vector.VectorMagnitude(cross2); // if (crossmag == 0) // { // //we are at least parallel, in fact we have proven we are totall parallel, now intersect // double Dx = startpt.X - currentedge.startendpt[1].X; // double Dy = startpt.Y - currentedge.startendpt[1].Y; // double Dz = startpt.Z - currentedge.startendpt[1].Z; // Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); // double Dmag = Vector.VectorMagnitude(D); // if (Cmag < guestmag && Dmag < guestmag) // { // //then it is inside as well, and test vector is engulfed by guest vector // kp.Value.relatedEdges.Add(currentedge); // //but the edge is still itself unique // currentedge.relatedEdges.Add(kp.Value); // edgecount++; // continue; // } // else // { // //I am pretty sure that by default, they are still neighbors and this is no difference // //it simply extends beyond one of the ends of the guest vector // kp.Value.relatedEdges.Add(currentedge); // //but the edge is still itself unique // currentedge.relatedEdges.Add(kp.Value); // edgecount++; // continue; // } // } // else // { // //we are not parallel, so this is not an adjacency match // edgecount++; // continue; // } // } // else // { // //if test edge start point [index 0] is outside, is one of the guest points inside? // //already computed B // double Cx = startpt.X - currentedge.startendpt[1].X; // double Cy = startpt.Y - currentedge.startendpt[1].Y; // double Cz = startpt.Z - currentedge.startendpt[1].Z; // Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); // double Cmag = Vector.VectorMagnitude(C); // edgeX = currentedge.startendpt[1].X - currentedge.startendpt[0].X; // edgeY = currentedge.startendpt[1].Y - currentedge.startendpt[0].Y; // edgeZ = currentedge.startendpt[1].Z - currentedge.startendpt[0].Z; // Vector.MemorySafe_CartVect edgevec = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); // double edgemag = Vector.VectorMagnitude(edgevec); // if (Cmag < edgemag && Bmag < edgemag) // { // //the guest edge's start point is inside the test edge // //guest edge point 2 // double Dx = endpt.X - currentedge.startendpt[1].X; // double Dy = endpt.Y - currentedge.startendpt[1].Y; // double Dz = endpt.Z - currentedge.startendpt[1].Z; // Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); // double Dmag = Vector.VectorMagnitude(D); // Vector.MemorySafe_CartVect cross3 = Vector.CrossProduct(D, edgevec); // crossmag = Vector.VectorMagnitude(cross3); // if (crossmag == 0) // { // //then we know the two edges are totall parallel and lined up // //determine if the guest edge point 2 is inside the test edge or outside of it // double Ex = startpt.X - currentedge.startendpt[1].X; // double Ey = startpt.Y - currentedge.startendpt[1].Y; // double Ez = startpt.Z - currentedge.startendpt[1].Z; // Vector.MemorySafe_CartVect E = new Vector.MemorySafe_CartVect(Ex, Ey, Ez); // double Emag = Vector.VectorMagnitude(E); // if (Dmag < edgemag && Emag < edgemag) // { // //it is inside // kp.Value.relatedEdges.Add(currentedge); // //but the edge is still itself unique // currentedge.relatedEdges.Add(kp.Value); // edgecount++; // continue; // } // else // { // //it is outside // kp.Value.relatedEdges.Add(currentedge); // //but the edge is still itself unique // currentedge.relatedEdges.Add(kp.Value); // edgecount++; // continue; // } // } // else // { // //we are not parallel, so this is not an adjacency match // edgecount++; // continue; // } // } // } // } // else // { // //they are not even parallel, so it is likely best just to shove on // edgecount++; // continue; // } //} #endregion } //this determines if it found the current edge to be unique, or not. if (edgecount == uniqueedges.Count) { uniqueedges.Add(distinctedges, currentedge); distinctedges++; } } } return uniqueedges; }
//this helps me to create an in-memory way to store the relationship between different edges. public static DOEgbXMLReportingObj FindMatchingEdges(DOEgbXML.gbXMLSpaces.ClosedShell cs, DOEgbXMLReportingObj report) { report.MessageList.Add("Starting test to find edge relationships for space closed shell polyloops."); try { Dictionary<int, DOEgbXMLBasics.EdgeFamily> edges = new Dictionary<int, DOEgbXMLBasics.EdgeFamily>(); int distinctedges = 0; for (int plcount = 0; plcount < cs.ploops.Count(); plcount++) { gbXMLSpaces.PolyLoop pl = cs.ploops[plcount]; int coordcount = pl.plcoords.Count; for (int i = 0; i < coordcount; i++) { //test edge DOEgbXMLBasics.EdgeFamily edge = new DOEgbXMLBasics.EdgeFamily(); edge.sbdec = plcount.ToString(); edge.relatedEdges = new List<DOEgbXMLBasics.EdgeFamily>(); edge.startendpt = new List<Vector.MemorySafe_CartCoord>(); if (edges.Count == 0) { edges[distinctedges] = edge; edge.startendpt.Add(pl.plcoords[i]); edge.startendpt.Add(pl.plcoords[i + 1]); edge.sbdec = plcount.ToString(); distinctedges++; continue; } //most edges work the same, in terms of the start and end point, except for the last edge (the else case) if (i < coordcount - 1) { edge.startendpt.Add(pl.plcoords[i]); edge.startendpt.Add(pl.plcoords[i + 1]); //search through existing edges to try and find a perfect match int edgecount = 0; //keeps track of how many guest edges in the dictionary I've searched through foreach (KeyValuePair<int, DOEgbXMLBasics.EdgeFamily> kp in edges) { Vector.MemorySafe_CartCoord startpt = kp.Value.startendpt[0]; //tolerance needed? if (startpt.X == edge.startendpt[0].X && startpt.Y == edge.startendpt[0].Y && startpt.Z == edge.startendpt[0].Z) { //found at least one perfect coordinate match, try to match the second Vector.MemorySafe_CartCoord endpt = kp.Value.startendpt[1]; if (endpt.X == edge.startendpt[1].X && endpt.Y == edge.startendpt[1].Y && endpt.Z == edge.startendpt[1].Z) { //both match, means the match is perfect, so add it to the related surfaces list kp.Value.relatedEdges.Add(edge); string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge "+startcoord+" , "+endcoord+" found a perfect match"); break; } else { //the edge may be unique, though it could still have neighboring relationships //draw vector A double Ax = endpt.X - edge.startendpt[1].X; double Ay = endpt.Y - edge.startendpt[1].Y; double Az = endpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect A = new Vector.MemorySafe_CartVect(Ax, Ay, Az); double Amag = Vector.VectorMagnitude(A); //take cross product to see if they are even in same plane double evX = endpt.X - startpt.X; double evY = endpt.Y - startpt.Y; double evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev = new Vector.MemorySafe_CartVect(evX, evY, evZ); double evmag = Vector.VectorMagnitude(ev); Vector.MemorySafe_CartVect cross = Vector.CrossProduct(A, ev); double crossmag = Vector.VectorMagnitude(cross); //tolerance? if (crossmag == 0) { //then we are at least parallel or antiparallel, now see if the point resides on the edge or outside of it double Bx = startpt.X - edge.startendpt[1].X; double By = startpt.Y - edge.startendpt[1].Y; double Bz = startpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect B = new Vector.MemorySafe_CartVect(Bx, By, Bz); double Bmag = Vector.VectorMagnitude(B); //check to see if the test edge is inside the guest edge if (Amag < evmag && Bmag < evmag) { //this means it lies on the plane at least, so it shares, but it is also still independent because a perfect match wasn't found kp.Value.relatedEdges.Add(edge); //accumulate its own relationships edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } double edgeX = edge.startendpt[1].X - edge.startendpt[0].X; double edgeY = edge.startendpt[1].Y - edge.startendpt[0].Y; double edgeZ = edge.startendpt[1].Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect edgevec = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); double edgemag = Vector.VectorMagnitude(edgevec); double Cx = startpt.X - edge.startendpt[1].X; double Cy = startpt.Y - edge.startendpt[1].Y; double Cz = startpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); double Dx = endpt.X - edge.startendpt[1].X; double Dy = endpt.Y - edge.startendpt[1].Y; double Dz = endpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); if (Dmag < edgemag && Cmag < edgemag) { //this means the test edge is longer than the guest edge, but they overlap kp.Value.relatedEdges.Add(edge); //the edge is still unique but accumulates a neighbor edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } } else { //this other point isn't relevant, and the edges don't coincide edgecount++; continue; } } } else if (startpt.X == edge.startendpt[1].X && startpt.Y == edge.startendpt[1].Y && startpt.Z == edge.startendpt[1].Z) { //found at least one perfect coordinate match, try to match the second Vector.MemorySafe_CartCoord endpt = kp.Value.startendpt[1]; if (endpt.X == edge.startendpt[0].X && endpt.Y == edge.startendpt[0].Y && endpt.Z == edge.startendpt[0].Z) { //both match, means the match is perfect, so add it to the related surfaces list kp.Value.relatedEdges.Add(edge); string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a perfect match"); break; } else { //the edge may be unique, though it could still have neighboring relationships double Ax = endpt.X - edge.startendpt[0].X; double Ay = endpt.Y - edge.startendpt[0].Y; double Az = endpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect A = new Vector.MemorySafe_CartVect(Ax, Ay, Az); double Amag = Vector.VectorMagnitude(A); //take cross product to see if they are even in same plane double evX = endpt.X - startpt.X; double evY = endpt.Y - startpt.Y; double evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev = new Vector.MemorySafe_CartVect(evX, evY, evZ); double evmag = Vector.VectorMagnitude(ev); Vector.MemorySafe_CartVect cross = Vector.CrossProduct(A, ev); double crossmag = Vector.VectorMagnitude(cross); //tolerance? if (crossmag == 0) { //then we are at least parallel or antiparallel, now see if the point resides on the edge or outside of it double Bx = startpt.X - edge.startendpt[0].X; double By = startpt.Y - edge.startendpt[0].Y; double Bz = startpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect B = new Vector.MemorySafe_CartVect(Bx, By, Bz); double Bmag = Vector.VectorMagnitude(B); //check to see if the test edge is inside the guest edge if (Amag < evmag && Bmag < evmag) { //this means it lies on the plane at least, so it shares, but it is also still independent because a perfect match wasn't found kp.Value.relatedEdges.Add(edge); //accumulate its own relationships edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } double edgeX = edge.startendpt[1].X - edge.startendpt[0].X; double edgeY = edge.startendpt[1].Y - edge.startendpt[0].Y; double edgeZ = edge.startendpt[1].Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect edgevec = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); double edgemag = Vector.VectorMagnitude(edgevec); double Cx = startpt.X - edge.startendpt[0].X; double Cy = startpt.Y - edge.startendpt[0].Y; double Cz = startpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); double Dx = endpt.X - edge.startendpt[0].X; double Dy = endpt.Y - edge.startendpt[0].Y; double Dz = endpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); if (Dmag < edgemag && Cmag < edgemag) { //this means the test edge is longer than the guest edge, but they overlap kp.Value.relatedEdges.Add(edge); //the edge is still unique but accumulates a neighbor edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } } else { //this other point isn't relevant, and the edges don't coincide edgecount++; continue; } } } //neither points perfectly coincide, so we do an exhaustive overlap check. else { Vector.MemorySafe_CartCoord endpt = kp.Value.startendpt[1]; //are the two vectors even parallel? because if they are not, no need to get more complex double evX = endpt.X - startpt.X; double evY = endpt.Y - startpt.Y; double evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev = new Vector.MemorySafe_CartVect(evX, evY, evZ); double edgeX = edge.startendpt[1].X - edge.startendpt[0].X; double edgeY = edge.startendpt[1].Y - edge.startendpt[0].Y; double edgeZ = edge.startendpt[1].Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect edgev = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); if (Vector.VectorMagnitude(Vector.CrossProduct(ev, edgev)) != 0) { //they are not even parallel so move on edgecount++; continue; } //try to determine if the two edges are parallel //test edge point 1 double Ax = endpt.X - edge.startendpt[0].X; double Ay = endpt.Y - edge.startendpt[0].Y; double Az = endpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect A = new Vector.MemorySafe_CartVect(Ax, Ay, Az); double Amag = Vector.VectorMagnitude(A); //take cross product to see if they are even in same plane evX = endpt.X - startpt.X; evY = endpt.Y - startpt.Y; evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev1 = new Vector.MemorySafe_CartVect(evX, evY, evZ); double guestmag = Vector.VectorMagnitude(ev1); Vector.MemorySafe_CartVect cross1 = Vector.CrossProduct(A, ev1); double crossmag = Vector.VectorMagnitude(cross1); //tolerance? if (crossmag == 0) { //we are at least parallel, now to check for a real intersection double Bx = startpt.X - edge.startendpt[0].X; double By = startpt.Y - edge.startendpt[0].Y; double Bz = startpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect B = new Vector.MemorySafe_CartVect(Bx, By, Bz); double Bmag = Vector.VectorMagnitude(B); //check to see if the test edge's first point (index 0) is totally inside the guest edge if (Amag < guestmag && Bmag < guestmag) { //the start point of the test edge is inside the guest edge //test edge point 2 against guest edge point 2 double Cx = endpt.X - edge.startendpt[1].X; double Cy = endpt.Y - edge.startendpt[1].Y; double Cz = endpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); Vector.MemorySafe_CartVect cross2 = Vector.CrossProduct(C, ev); crossmag = Vector.VectorMagnitude(cross2); if (crossmag == 0) { //we are at least parallel, in fact we have proven we are totall parallel, now intersect double Dx = startpt.X - edge.startendpt[1].X; double Dy = startpt.Y - edge.startendpt[1].Y; double Dz = startpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); if (Cmag < guestmag && Dmag < guestmag) { //then it is inside as well, and test vector is engulfed by guest vector kp.Value.relatedEdges.Add(edge); //but the edge is still itself unique edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } else { //I am pretty sure that by default, they are still neighbors and this is no difference //it simply extends beyond one of the ends of the guest vector kp.Value.relatedEdges.Add(edge); //but the edge is still itself unique edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } } else { //we are not parallel, so this is not an adjacency match edgecount++; continue; } } else { //if test edge start point [index 0] is outside, is one of the guest points inside? //already computed B double Cx = startpt.X - edge.startendpt[1].X; double Cy = startpt.Y - edge.startendpt[1].Y; double Cz = startpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); edgeX = edge.startendpt[1].X - edge.startendpt[0].X; edgeY = edge.startendpt[1].Y - edge.startendpt[0].Y; edgeZ = edge.startendpt[1].Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect edgevec = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); double edgemag = Vector.VectorMagnitude(edgevec); if (Cmag < edgemag && Bmag < edgemag) { //the guest edge's start point is inside the test edge //guest edge point 2 double Dx = endpt.X - edge.startendpt[1].X; double Dy = endpt.Y - edge.startendpt[1].Y; double Dz = endpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); Vector.MemorySafe_CartVect cross3 = Vector.CrossProduct(D, edgevec); crossmag = Vector.VectorMagnitude(cross3); if (crossmag == 0) { //then we know the two edges are totall parallel and lined up //determine if the guest edge point 2 is inside the test edge or outside of it double Ex = startpt.X - edge.startendpt[1].X; double Ey = startpt.Y - edge.startendpt[1].Y; double Ez = startpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect E = new Vector.MemorySafe_CartVect(Ex, Ey, Ez); double Emag = Vector.VectorMagnitude(E); if (Dmag < edgemag && Emag < edgemag) { //it is inside kp.Value.relatedEdges.Add(edge); //but the edge is still itself unique edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } else { //it is outside kp.Value.relatedEdges.Add(edge); //but the edge is still itself unique edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } } else { //we are not parallel, so this is not an adjacency match edgecount++; continue; } } } } else { //they are not even parallel, so it is likely best just to shove on edgecount++; continue; } } } //this determines if it found a matching edge if (edgecount == edges.Count) { edges.Add(distinctedges, edge); distinctedges++; } } //last edge end edge is the zero index else { edge.startendpt.Add(pl.plcoords[i]); edge.startendpt.Add(pl.plcoords[0]); int edgecount = 0; //keeps track of how many guest edges in the dictionary I've searched through foreach (KeyValuePair<int, DOEgbXMLBasics.EdgeFamily> kp in edges) { Vector.MemorySafe_CartCoord startpt = kp.Value.startendpt[0]; //tolerance needed? if (startpt.X == edge.startendpt[0].X && startpt.Y == edge.startendpt[0].Y && startpt.Z == edge.startendpt[0].Z) { //found at least one perfect coordinate match, try to match the second Vector.MemorySafe_CartCoord endpt = kp.Value.startendpt[1]; if (endpt.X == edge.startendpt[1].X && endpt.Y == edge.startendpt[1].Y && endpt.Z == edge.startendpt[1].Z) { //both match, means the match is perfect, so add it to the related surfaces list kp.Value.relatedEdges.Add(edge); string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a perfect match"); break; } else { //the edge may be unique, though it could still have neighboring relationships //draw vector A double Ax = endpt.X - edge.startendpt[1].X; double Ay = endpt.Y - edge.startendpt[1].Y; double Az = endpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect A = new Vector.MemorySafe_CartVect(Ax, Ay, Az); double Amag = Vector.VectorMagnitude(A); //take cross product to see if they are even in same plane double evX = endpt.X - startpt.X; double evY = endpt.Y - startpt.Y; double evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev = new Vector.MemorySafe_CartVect(evX, evY, evZ); double evmag = Vector.VectorMagnitude(ev); Vector.MemorySafe_CartVect cross = Vector.CrossProduct(A, ev); double crossmag = Vector.VectorMagnitude(cross); //tolerance? if (crossmag == 0) { //then we are at least parallel or antiparallel, now see if the point resides on the edge or outside of it double Bx = startpt.X - edge.startendpt[1].X; double By = startpt.Y - edge.startendpt[1].Y; double Bz = startpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect B = new Vector.MemorySafe_CartVect(Bx, By, Bz); double Bmag = Vector.VectorMagnitude(B); //check to see if the test edge is inside the guest edge if (Amag < evmag && Bmag < evmag) { //this means it lies on the plane at least, so it shares, but it is also still independent because a perfect match wasn't found kp.Value.relatedEdges.Add(edge); //accumulate its own relationships edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } double edgeX = edge.startendpt[1].X - edge.startendpt[0].X; double edgeY = edge.startendpt[1].Y - edge.startendpt[0].Y; double edgeZ = edge.startendpt[1].Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect edgevec = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); double edgemag = Vector.VectorMagnitude(edgevec); double Cx = startpt.X - edge.startendpt[1].X; double Cy = startpt.Y - edge.startendpt[1].Y; double Cz = startpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); double Dx = endpt.X - edge.startendpt[1].X; double Dy = endpt.Y - edge.startendpt[1].Y; double Dz = endpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); if (Dmag < edgemag && Cmag < edgemag) { //this means the test edge is longer than the guest edge, but they overlap kp.Value.relatedEdges.Add(edge); //the edge is still unique but accumulates a neighbor edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } } else { //this other point isn't relevant, and the edges don't coincide edgecount++; continue; } } } else if (startpt.X == edge.startendpt[1].X && startpt.Y == edge.startendpt[1].Y && startpt.Z == edge.startendpt[1].Z) { //found at least one perfect coordinate match, try to match the second Vector.MemorySafe_CartCoord endpt = kp.Value.startendpt[1]; if (endpt.X == edge.startendpt[0].X && endpt.Y == edge.startendpt[0].Y && endpt.Z == edge.startendpt[0].Z) { //both match, means the match is perfect, so add it to the related surfaces list kp.Value.relatedEdges.Add(edge); string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a perfect match"); break; } else { //the edge may be unique, though it could still have neighboring relationships double Ax = endpt.X - edge.startendpt[0].X; double Ay = endpt.Y - edge.startendpt[0].Y; double Az = endpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect A = new Vector.MemorySafe_CartVect(Ax, Ay, Az); double Amag = Vector.VectorMagnitude(A); //take cross product to see if they are even in same plane double evX = endpt.X - startpt.X; double evY = endpt.Y - startpt.Y; double evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev = new Vector.MemorySafe_CartVect(evX, evY, evZ); double evmag = Vector.VectorMagnitude(ev); Vector.MemorySafe_CartVect cross = Vector.CrossProduct(A, ev); double crossmag = Vector.VectorMagnitude(cross); //tolerance? if (crossmag == 0) { //then we are at least parallel or antiparallel, now see if the point resides on the edge or outside of it double Bx = startpt.X - edge.startendpt[0].X; double By = startpt.Y - edge.startendpt[0].Y; double Bz = startpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect B = new Vector.MemorySafe_CartVect(Bx, By, Bz); double Bmag = Vector.VectorMagnitude(B); //check to see if the test edge is inside the guest edge if (Amag < evmag && Bmag < evmag) { //this means it lies on the plane at least, so it shares, but it is also still independent because a perfect match wasn't found kp.Value.relatedEdges.Add(edge); //accumulate its own relationships edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } double edgeX = edge.startendpt[1].X - edge.startendpt[0].X; double edgeY = edge.startendpt[1].Y - edge.startendpt[0].Y; double edgeZ = edge.startendpt[1].Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect edgevec = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); double edgemag = Vector.VectorMagnitude(edgevec); double Cx = startpt.X - edge.startendpt[0].X; double Cy = startpt.Y - edge.startendpt[0].Y; double Cz = startpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); double Dx = endpt.X - edge.startendpt[0].X; double Dy = endpt.Y - edge.startendpt[0].Y; double Dz = endpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); if (Dmag < edgemag && Cmag < edgemag) { //this means the test edge is longer than the guest edge, but they overlap kp.Value.relatedEdges.Add(edge); //the edge is still unique but accumulates a neighbor edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } } else { //this other point isn't relevant, and the edges don't coincide edgecount++; continue; } } } //neither points perfectly coincide, so we do an exhaustive overlap check. else { Vector.MemorySafe_CartCoord endpt = kp.Value.startendpt[1]; //are the two vectors even parallel? because if they are not, no need to get more complex double evX = endpt.X - startpt.X; double evY = endpt.Y - startpt.Y; double evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev = new Vector.MemorySafe_CartVect(evX, evY, evZ); double edgeX = edge.startendpt[1].X - edge.startendpt[0].X; double edgeY = edge.startendpt[1].Y - edge.startendpt[0].Y; double edgeZ = edge.startendpt[1].Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect edgev = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); if (Vector.VectorMagnitude(Vector.CrossProduct(ev, edgev)) != 0) { //they are not even parallel so move on edgecount++; continue; } //try to determine if the two edges are parallel //test edge point 1 double Ax = endpt.X - edge.startendpt[0].X; double Ay = endpt.Y - edge.startendpt[0].Y; double Az = endpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect A = new Vector.MemorySafe_CartVect(Ax, Ay, Az); double Amag = Vector.VectorMagnitude(A); //take cross product to see if they are even in same plane evX = endpt.X - startpt.X; evY = endpt.Y - startpt.Y; evZ = endpt.Z - startpt.Z; Vector.MemorySafe_CartVect ev1 = new Vector.MemorySafe_CartVect(evX, evY, evZ); double guestmag = Vector.VectorMagnitude(ev); Vector.MemorySafe_CartVect cross1 = Vector.CrossProduct(A, ev); double crossmag = Vector.VectorMagnitude(cross1); //tolerance? if (crossmag == 0) { //we are at least parallel, now to check for a real intersection double Bx = startpt.X - edge.startendpt[0].X; double By = startpt.Y - edge.startendpt[0].Y; double Bz = startpt.Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect B = new Vector.MemorySafe_CartVect(Bx, By, Bz); double Bmag = Vector.VectorMagnitude(B); //check to see if the test edge's first point (index 0) is totally inside the guest edge if (Amag < guestmag && Bmag < guestmag) { //the start point of the test edge is inside the guest edge //test edge point 2 against guest edge point 2 double Cx = endpt.X - edge.startendpt[1].X; double Cy = endpt.Y - edge.startendpt[1].Y; double Cz = endpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); Vector.MemorySafe_CartVect cross2 = Vector.CrossProduct(C, ev); crossmag = Vector.VectorMagnitude(cross2); if (crossmag == 0) { //we are at least parallel, in fact we have proven we are totall parallel, now intersect double Dx = startpt.X - edge.startendpt[1].X; double Dy = startpt.Y - edge.startendpt[1].Y; double Dz = startpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); if (Cmag < guestmag && Dmag < guestmag) { //then it is inside as well, and test vector is engulfed by guest vector kp.Value.relatedEdges.Add(edge); //but the edge is still itself unique edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } else { //I am pretty sure that by default, they are still neighbors and this is no difference //it simply extends beyond one of the ends of the guest vector kp.Value.relatedEdges.Add(edge); //but the edge is still itself unique edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } } else { //we are not parallel, so this is not an adjacency match edgecount++; continue; } } else { //if test edge start point [index 0] is outside, is one of the guest points inside? //already computed B double Cx = startpt.X - edge.startendpt[1].X; double Cy = startpt.Y - edge.startendpt[1].Y; double Cz = startpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect C = new Vector.MemorySafe_CartVect(Cx, Cy, Cz); double Cmag = Vector.VectorMagnitude(C); edgeX = edge.startendpt[1].X - edge.startendpt[0].X; edgeY = edge.startendpt[1].Y - edge.startendpt[0].Y; edgeZ = edge.startendpt[1].Z - edge.startendpt[0].Z; Vector.MemorySafe_CartVect edgevec = new Vector.MemorySafe_CartVect(edgeX, edgeY, edgeZ); double edgemag = Vector.VectorMagnitude(edgevec); if (Cmag < edgemag && Bmag < edgemag) { //the guest edge's start point is inside the test edge //guest edge point 2 double Dx = endpt.X - edge.startendpt[1].X; double Dy = endpt.Y - edge.startendpt[1].Y; double Dz = endpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect D = new Vector.MemorySafe_CartVect(Dx, Dy, Dz); double Dmag = Vector.VectorMagnitude(D); Vector.MemorySafe_CartVect cross3 = Vector.CrossProduct(D, edgevec); crossmag = Vector.VectorMagnitude(cross3); if (crossmag == 0) { //then we know the two edges are totall parallel and lined up //determine if the guest edge point 2 is inside the test edge or outside of it double Ex = startpt.X - edge.startendpt[1].X; double Ey = startpt.Y - edge.startendpt[1].Y; double Ez = startpt.Z - edge.startendpt[1].Z; Vector.MemorySafe_CartVect E = new Vector.MemorySafe_CartVect(Ex, Ey, Ez); double Emag = Vector.VectorMagnitude(E); if (Dmag < edgemag && Emag < edgemag) { //it is inside kp.Value.relatedEdges.Add(edge); //but the edge is still itself unique edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } else { //it is outside kp.Value.relatedEdges.Add(edge); //but the edge is still itself unique edge.relatedEdges.Add(kp.Value); edgecount++; string startcoord = MakeCoordString(edge.startendpt[0]); string endcoord = MakeCoordString(edge.startendpt[1]); report.MessageList.Add("Edge " + startcoord + " , " + endcoord + " found a match"); continue; } } else { //we are not parallel, so this is not an adjacency match edgecount++; continue; } } } } else { //they are not even parallel, so it is likely best just to shove on edgecount++; continue; } } } //this determines if it found a matching edge if (edgecount == edges.Count) { edges.Add(distinctedges, edge); distinctedges++; } } } } } catch (Exception e) { report.longMsg = e.ToString(); report.MessageList.Add("This test has failed unexpectedly."); report.passOrFail = false; return report; } return report; }
public bool EdgesAreValid(Dictionary<int,DOEgbXMLBasics.EdgeFamily> edges) { //stores the findings of each unique edge test Dictionary<int, bool> edgeResults = new Dictionary<int, bool>(); foreach(KeyValuePair<int,DOEgbXMLBasics.EdgeFamily> kp in edges) { var edge = kp.Value; var lengthTol = DOEgbXMLBasics.Tolerances.SurfacePLCoordTolerance; Vector.MemorySafe_CartVect edgeVec = Vector.CreateMemorySafe_Vector(edge.startendpt[0], edge.startendpt[1]); double edgeMag = Vector.VectorMagnitude(edgeVec); double edgesLength = 0; for(int re = 0; re< edge.relatedEdges.Count(); re++) { Vector.MemorySafe_CartVect e = Vector.CreateMemorySafe_Vector(edge.relatedEdges[re].startendpt[0], edge.relatedEdges[re].startendpt[1]); double mag = Vector.VectorMagnitude(e); edgesLength += mag; } if(Math.Abs(edgesLength - edgeMag) < lengthTol) { //check for case where the edges endpoints should match nearly exactly if(edge.relatedEdges.Count() == 1) { double diffx = Math.Abs(edge.startendpt[0].X - edge.relatedEdges[0].startendpt[0].X); double diffy = Math.Abs(edge.startendpt[0].Y - edge.relatedEdges[0].startendpt[0].Y); double diffz = Math.Abs(edge.startendpt[0].Z - edge.relatedEdges[0].startendpt[0].Z); if(diffx <= lengthTol && diffy <= lengthTol && diffz <= lengthTol) { diffx = Math.Abs(edge.startendpt[1].X - edge.relatedEdges[0].startendpt[1].X); diffy = Math.Abs(edge.startendpt[1].Y - edge.relatedEdges[0].startendpt[1].Y); diffz = Math.Abs(edge.startendpt[1].Z - edge.relatedEdges[0].startendpt[1].Z); if(diffx <= lengthTol && diffy <= lengthTol && diffz <= lengthTol) { //edges match edgeResults[kp.Key] = true; } } diffx = Math.Abs(edge.startendpt[1].X - edge.relatedEdges[0].startendpt[0].X); diffy = Math.Abs(edge.startendpt[1].Y - edge.relatedEdges[0].startendpt[0].Y); diffz = Math.Abs(edge.startendpt[1].Z - edge.relatedEdges[0].startendpt[0].Z); if (diffx <= lengthTol && diffy <= lengthTol && diffz <= lengthTol) { diffx = Math.Abs(edge.startendpt[0].X - edge.relatedEdges[0].startendpt[1].X); diffy = Math.Abs(edge.startendpt[0].Y - edge.relatedEdges[0].startendpt[1].Y); diffz = Math.Abs(edge.startendpt[0].Z - edge.relatedEdges[0].startendpt[1].Z); if (diffx <= lengthTol && diffy <= lengthTol && diffz <= lengthTol) { //edges match edgeResults[kp.Key] = true; } } } else { //there is more than one related edge for the given edge int validRelatedEdgesCount = 0; List<DOEgbXMLBasics.EdgeFamily> middleEdges = new List<DOEgbXMLBasics.EdgeFamily>(); DOEgbXMLBasics.EdgeFamily startEdge = new DOEgbXMLBasics.EdgeFamily(); DOEgbXMLBasics.EdgeFamily endEdge = new DOEgbXMLBasics.EdgeFamily(); //perform a standard parametric line check //this finds the indices of the related edges that share the start and end point of the edge var edgeStartPt = edge.startendpt[0]; var edgeEndPt = edge.startendpt[1]; for(int re = 0; re< edge.relatedEdges.Count(); re++) { var relatedEdge = edge.relatedEdges[re]; double startdX = Math.Abs(relatedEdge.startendpt[0].X - edgeStartPt.X); double startdY = Math.Abs(relatedEdge.startendpt[0].Y - edgeStartPt.Y); double startdZ = Math.Abs(relatedEdge.startendpt[0].Z - edgeStartPt.Z); if(startdX <= lengthTol && startdY <= lengthTol && startdZ <= lengthTol) { startEdge = relatedEdge; continue; } startdX = Math.Abs(relatedEdge.startendpt[1].X - edgeStartPt.X); startdY = Math.Abs(relatedEdge.startendpt[1].Y - edgeStartPt.Y); startdZ = Math.Abs(relatedEdge.startendpt[1].Z - edgeStartPt.Z); if (startdX <= lengthTol && startdY <= lengthTol && startdZ <= lengthTol) { startEdge = relatedEdge; continue; } double enddX = Math.Abs(relatedEdge.startendpt[1].X - edgeEndPt.X); double enddY = Math.Abs(relatedEdge.startendpt[1].Y - edgeEndPt.Y); double enddZ = Math.Abs(relatedEdge.startendpt[1].Z - edgeEndPt.Z); if (enddX <= lengthTol && enddY <= lengthTol && enddZ <= lengthTol) { endEdge = relatedEdge; continue; } enddX = Math.Abs(relatedEdge.startendpt[0].X - edgeEndPt.X); enddY = Math.Abs(relatedEdge.startendpt[0].Y - edgeEndPt.Y); enddZ = Math.Abs(relatedEdge.startendpt[0].Z - edgeEndPt.Z); if (enddX <= lengthTol && enddY <= lengthTol && enddZ <= lengthTol) { endEdge = relatedEdge; continue; } middleEdges.Add(relatedEdge); } //now I should have a startEdge, middleEdges, and an end Edge. It is legal for there to be no middleEdges //it is illegal for the start and end edge to be undefined. if(startEdge.relatedEdges.Count == 0 || endEdge.relatedEdges.Count == 0) { logger.Info("Something"); return false; } //an algorithm to make sure all the edges line up well. We should have already established that they are parallel when finding edges previously. if(middleEdges.Count == 0) { if(EdgesShareVertex(startEdge,endEdge)) { //this should be a sufficient test, because //the edges are parallel, the start edge is at the start vertex , the end edge is at the other vertex //there are no middle edges //the sum of these two edges is equal to the length of the edge in the keyvalue pair. edgeResults[kp.Key] = true; } else { edgeResults[kp.Key] = false; } } else { //there are middle edges int validRelatedEdgesCt = 0; //one simple way to do this is to check to see if all vertices can find a counterpart for(int me = 0 ; me < middleEdges.Count();me++) { int validatedVertices = 0; foreach(var pt in middleEdges[me].startendpt) { if (EdgesShareVertex(pt, startEdge)) { validatedVertices++; validRelatedEdgesCount++; } //we add here because startedge is now completely valid if (EdgesShareVertex(pt, endEdge)) { validatedVertices++; } if (FoundVertexMatch(pt, middleEdges)) { validatedVertices++; validRelatedEdgesCount++; } //we add here because endedge is now completely valid } if(validatedVertices == 2) { validRelatedEdgesCount++; } } if (validRelatedEdgesCt == edge.relatedEdges.Count) { edgeResults[kp.Key] = true; } else { edgeResults[kp.Key] = false; } //another method, TBD, is to create a vector with each related edge, find its scalar to the edge, and the scalars should sum to 1 } } } else { //related edges exceed length of the edge //TBD for future validation exercises } } var keys = edgeResults.Where(x => x.Value==false).Select(x => x.Key); if (keys.Count() > 0) { return false; } else { return true; } }
public static DOEgbXMLReportingObj areSpacesEnclosed(List<gbXMLSpaces> spaces, DOEgbXMLReportingObj report, bool waterTightRequired) { report.testSummary += "This test ensures that each space object is reasonably enclosed"; report.TestPassedDict = new Dictionary<string, bool>(); List<DOEgbXMLBasics.EdgeFamily> eflist = new List<DOEgbXMLBasics.EdgeFamily>(); try { report.MessageList.Add("Starting space enclosure test."); if (waterTightRequired) { report.MessageList.Add("Performing tests for watertight, or nearly watertight enclosures."); report.MessageList.Add("The tolerance for tests is: " + report.tolerance); //check the closed shell polygon //if the surfaces are discretized this simple check may not work., and I have another approach at the end of the routine. int edgessearched = 0; int edgesfound = 0; for (int count = 0; count < spaces.Count(); count++) { report.MessageList.Add("Checking Space: " + spaces[count].id); for (int plcount = 0; plcount < spaces[count].sg.cs.ploops.Count(); plcount++) { PolyLoop pl = spaces[count].sg.cs.ploops[plcount]; for(int coordcount = 0; coordcount < pl.plcoords.Count; coordcount++) { edgessearched++; DOEgbXMLBasics.EdgeFamily ef = new DOEgbXMLBasics.EdgeFamily(); ef.sbdec = spaces[count].id + "_" + plcount + "_" + coordcount; ef.relatedEdges = new List<DOEgbXMLBasics.EdgeFamily>(); ef.startendpt = new List<Vector.MemorySafe_CartCoord>(); if (plcount == 0 && coordcount == 0) { ef.relatedEdges[edgessearched] = ef; Vector.MemorySafe_CartCoord startpt = pl.plcoords[coordcount]; Vector.MemorySafe_CartCoord endpt = pl.plcoords[coordcount + 1]; ef.startendpt.Add(startpt); ef.startendpt.Add(endpt); continue; } if (coordcount < pl.plcoords.Count() - 1) { Vector.MemorySafe_CartCoord startpt = pl.plcoords[coordcount]; Vector.MemorySafe_CartCoord endpt = pl.plcoords[coordcount + 1]; //search all the other polyloops except for this polyloop for (int innerplcount = 0; innerplcount < spaces[count].sg.cs.ploops.Count(); innerplcount++) { if (innerplcount == plcount) continue; PolyLoop testpl = spaces[count].sg.cs.ploops[innerplcount]; for (int testcoord = 0; testcoord < testpl.plcoords.Count(); testcoord++) { if (testcoord < testpl.plcoords.Count()) { Vector.MemorySafe_CartCoord teststart = testpl.plcoords[testcoord]; Vector.MemorySafe_CartCoord testend = testpl.plcoords[testcoord + 1]; double diffX = Math.Abs(startpt.X - teststart.X); double diffY = Math.Abs(startpt.Y - teststart.Y); double diffZ = Math.Abs(startpt.Z - teststart.Z); if (diffX < report.tolerance && diffY < report.tolerance && diffZ < report.tolerance) { edgesfound++; } } else { Vector.MemorySafe_CartCoord teststart = testpl.plcoords[testcoord]; Vector.MemorySafe_CartCoord testend = testpl.plcoords[0]; double diffX = Math.Abs(startpt.X - teststart.X); double diffY = Math.Abs(startpt.Y - teststart.Y); double diffZ = Math.Abs(startpt.Z - teststart.Z); if (diffX < report.tolerance && diffY < report.tolerance && diffZ < report.tolerance) { edgesfound++; } } } } } } } } } else { //we may be able to perform a lower-grade test } } catch (Exception e) { report.longMsg = e.ToString(); report.MessageList.Add("This test failed unexpectedly."); report.passOrFail = false; return report; } return report; }