private TVGLConvexHull CreateCombinedConvexHull(TVGLConvexHull refCVXHull, TVGLConvexHull movingCVXHull) { var pointCloud = new List <Vertex>(refCVXHull.Vertices); pointCloud.AddRange(movingCVXHull.Vertices); return(new TVGLConvexHull(pointCloud, 1e-8)); }
public SubAssembly(Part refAssembly, Part movingAssembly, TVGLConvexHull combinedCVXHull, InstallCharacterType InstallCharacter, List <PolygonalFace> refFacesInCombined) { PartNames = new List <string>(refAssembly.PartNames); PartNames.AddRange(movingAssembly.PartNames); Name = "subasm-" + PartNames.Aggregate((i, j) => i + "," + j); Install = new InstallAction { Reference = refAssembly, Moving = movingAssembly }; InstallModelInputs = new double[1, 6]; Secure = new SecureAction(); Rotate = new RotateAction(); RotateModelInputs = new double[1, 5]; MoveRoate = new MoveRotateAction(); MoveRoateModelInputs = new double[1, 5]; this.InstallCharacter = InstallCharacter; Mass = refAssembly.Mass + movingAssembly.Mass; Volume = refAssembly.Volume + movingAssembly.Volume; //volume of sphere = (4/3)*Math.Pi*r*r*r var radius = Math.Pow(0.75 * Volume / Math.PI, 1.0 / 3.0); AvgMomentofInertia = Mass * radius * radius; CVXHull = combinedCVXHull; this.refFacesInCombined = refFacesInCombined; InternalStabilityInfo = new InternalStability(); InternalStabilityInfo.needfixture = false; }
public SubAssembly(HashSet <Component> nodes, TVGLConvexHull combinedCVXHull, double Mass, double Volume, Vertex centerOfMass) { PartNames = nodes.Select(n => n.name).ToList(); Name = Name = "subasm-" + PartNames.Aggregate((i, j) => i + "," + j); this.Mass = Mass; this.Volume = Volume; //volume of sphere = (4/3)*Math.Pi*r*r*r var radius = Math.Pow(0.75 * Volume / Math.PI, 1.0 / 3.0); AvgMomentofInertia = Mass * radius * radius; CVXHull = combinedCVXHull; CenterOfMass = centerOfMass; }
public Part(string name, double mass, double volume, TVGLConvexHull convexHull, Vertex centerOfMass) { Name = name; PartNames = new List <string>(); PartNames.Add(name); Mass = mass; Volume = volume; //volume of sphere = (4/3)*Math.Pi*r*r*r var radius = Math.Pow(0.75 * volume / Math.PI, 1.0 / 3.0); AvgMomentofInertia = mass * radius * radius; CVXHull = convexHull; /*var com = new Vector(0, 0, 0); * // find install direction by averaging all visible_DOF * if (convexHull!=null) * foreach (var pt in convexHull.Vertices) * com.AddInPlace(pt);*/ //CenterOfMass = new Vertex(StarMath.divide(com.Position, convexHull.Points.Count(), 3)); CenterOfMass = centerOfMass; }
private InstallCharacterType shouldReferenceAndMovingBeSwitched(Part refAssembly, Part movingAssembly, TVGLConvexHull combinedCVXHull, out List <PolygonalFace> refFacesInCombined, out List <PolygonalFace> movingFacesInCombined) { /* first, create a list of vertices from the reference hull that are present in the combined hull. * likewise, with the moving. */ var refVertsInCombined = new List <Vertex>(); var movingVertsInCombined = new List <Vertex>(); foreach (var pt in combinedCVXHull.Vertices) { if (refAssembly.CVXHull.Vertices.Contains(pt)) { refVertsInCombined.Add(pt); } else { /* this additional Contains function is unnecessary and potential time-consuming. * It was implemented for initial validiation, but it is commented out now. * if (!movingAssembly.CVXHull.Points.Contains(pt)) * throw new Exception("The point is in neither original part!"); */ movingVertsInCombined.Add(pt); } } /* If none of the combined vertices are from the moving, we can end this function early and save time. */ if (movingVertsInCombined.Count == 0) { movingFacesInCombined = null; refFacesInCombined = new List <PolygonalFace>(combinedCVXHull.Faces); return(InstallCharacterType.MovingIsInsideReference); } /* ...likewise for the original reference */ if (refVertsInCombined.Count == 0) { refFacesInCombined = null; movingFacesInCombined = new List <PolygonalFace>(combinedCVXHull.Faces); return(InstallCharacterType.ReferenceIsInsideMoving); } /* we could just count the number of vertices, but that would not be as accurate a prediction * as the area of the faces */ refFacesInCombined = new List <PolygonalFace>(); movingFacesInCombined = new List <PolygonalFace>(); double refFaceArea = 0.0; var movingFaceArea = 0.0; var totalFaceArea = 0.0; foreach (var face in combinedCVXHull.Faces) { var faceArea = findFaceArea(face); totalFaceArea += faceArea; if (face.Vertices.All(v => refAssembly.CVXHull.Vertices.Contains(v))) { refFacesInCombined.Add(face); refFaceArea += faceArea; } else if (face.Vertices.All(v => movingAssembly.CVXHull.Vertices.Contains(v))) { movingFacesInCombined.Add(face); movingFaceArea += faceArea; } } /* former faces is the sum areas of faces from prior cvx hulls */ var formerFacesArea = refFaceArea + movingFaceArea; /* if the former face area does not take up a significant portion of * the new faces then we do not have the confidence to make the judgement * based on this fact. */ if (formerFacesArea / totalFaceArea > Constants.CVXFormerFaceConfidence) { /* there are two check here: if the common area is very small, we assume the * subassembly is inside the other. If not, maybe it is more on the outside * but a smaller effect on resulting convex hull. */ if (refFaceArea / formerFacesArea < Constants.CVXOnInsideThreshold) { return(InstallCharacterType.ReferenceIsInsideMoving); } if (movingFaceArea / formerFacesArea < Constants.CVXOnInsideThreshold) { return(InstallCharacterType.MovingIsInsideReference); } if (refFaceArea / formerFacesArea < Constants.CVXOnOutsideThreshold) { return(InstallCharacterType.ReferenceIsOnOutsideOfMoving); } if (movingFaceArea / formerFacesArea < Constants.CVXOnOutsideThreshold) { return(InstallCharacterType.MovingIsOnOutsideOfReference); } } /* if we cannot confidently use face area then we switch to comparing * the magnitudes of the moment of inertia. */ else { if (refAssembly.AvgMomentofInertia >= movingAssembly.AvgMomentofInertia) { return(InstallCharacterType.MovingReferenceSimiliar); } else { return(InstallCharacterType.ReferenceMovingSimiliarSwitch); } } /* this will not be invoked, but it is left as a final result in case these heuristic cases should change. */ return(InstallCharacterType.Unknown); }
public SubAssembly Update(option opt, List <Component> rest, Dictionary <string, TVGLConvexHull> convexHullForParts) { Part refAssembly, movingAssembly; //if (ActionIsAssemblyByAssembly()) //{ // //var node0 = (Component)opt.nodes[0]; // //var node1 = (Component)opt.nodes[1]; // //var node0name = node0.name; // //var node1name = node1.name; // //refAssembly = Subassemblies.FirstOrDefault(subasm => subasm.PartNames.Contains(node0name)); // //if (refAssembly == null) // // refAssembly = new Part(node0name, GetPartMass(node0), GetPartVolume(node0), // // convexHullForParts[node0name], GetPartCenterOfMass(node0)); // //else Subassemblies.Remove((SubAssembly) refAssembly); // //movingAssembly = Subassemblies.FirstOrDefault(subasm => subasm.PartNames.Contains(node1name)); // //if (movingAssembly == null) // // movingAssembly = new Part(node1name, GetPartMass(node1), GetPartVolume(node1), // // convexHullForParts[node1name], GetPartCenterOfMass(node0)); // //else Subassemblies.Remove((SubAssembly) movingAssembly); //} //else if (ActionIsRemoveSCC()) //{ var movingNodes = opt.Nodes.Cast <Component>().ToList(); var newSubAsmNodes = rest; if (movingNodes.Count == 1) { var nodeName = movingNodes[0].name; movingAssembly = new Part(nodeName, GetPartMass(movingNodes[0]), GetPartVolume(movingNodes[0]), convexHullForParts[nodeName], GetPartCenterOfMass(movingNodes[0])); } else { var combinedCVXHullM = CreateCombinedConvexHull2(movingNodes, convexHullForParts); var VolumeM = GetSubassemblyVolume(movingNodes); var MassM = GetSubassemblyMass(movingNodes); var centerOfMass = GetSubassemblyCenterOfMass(movingNodes); movingAssembly = new SubAssembly(new HashSet <Component>(movingNodes), combinedCVXHullM, MassM, VolumeM, centerOfMass); } var referenceHyperArcnodes = new List <Component>(); referenceHyperArcnodes = newSubAsmNodes.Where(a => !movingNodes.Contains(a)).ToList(); if (referenceHyperArcnodes.Count == 1) { var nodeName = referenceHyperArcnodes[0].name; refAssembly = new Part(nodeName, GetPartMass(referenceHyperArcnodes[0]), GetPartVolume(referenceHyperArcnodes[0]), convexHullForParts[nodeName], GetPartCenterOfMass(referenceHyperArcnodes[0])); } else { var combinedCVXHullR = CreateCombinedConvexHull2(referenceHyperArcnodes, convexHullForParts); var VolumeR = GetSubassemblyVolume(referenceHyperArcnodes); var MassR = GetSubassemblyMass(referenceHyperArcnodes); var centerOfMass = GetSubassemblyCenterOfMass(referenceHyperArcnodes); refAssembly = new SubAssembly(new HashSet <Component>(referenceHyperArcnodes), combinedCVXHullR, MassR, VolumeR, centerOfMass); } //} //else throw new Exception("Only install rules in assembly at this point."); TVGLConvexHull combinedCVXHull = CreateCombinedConvexHull( refAssembly.CVXHull, movingAssembly.CVXHull); //List<PolygonalFace> refFacesInCombined, movingFacesInCombined; var InstallCharacter = shouldReferenceAndMovingBeSwitched(refAssembly, movingAssembly, combinedCVXHull, out refFacesInCombined, out movingFacesInCombined); if ((int)InstallCharacter < 0) { var tempASM = refAssembly; refAssembly = movingAssembly; movingAssembly = tempASM; refFacesInCombined = movingFacesInCombined; // no need to use temp here, as the movingFaces in the // combined convex hull are not needed. InstallCharacter = (InstallCharacterType)(-((int)InstallCharacter)); } string refName = NameMaker(refAssembly); string movName = NameMaker(movingAssembly); var newSubassembly = new SubAssembly(refAssembly, movingAssembly, combinedCVXHull, InstallCharacter, refFacesInCombined); //newSubassembly.Name = refName +" on "+movName; newSubassembly.CenterOfMass = CombinedCenterOfMass(newSubassembly); // instead of adding to Subassemblies, newSubassembly must be added to its preceeding subassembly (to its parent) Subassemblies.Add(newSubassembly); return(newSubassembly); }