public CFace MapFace(Vector3[] positions) { CFace f = new CFace(); f.solid = this; f.points = new int[positions.Length]; for (int i = 0; i < positions.Length; ++i) { bool found = false; for (int j = 0; j < vertices.Count; ++j) { if (vertices[j].position == positions[i]) { f.points[i] = j; found = true; break; } } if (!found) { f.points[i] = vertices.Count; vertices.Add(new CPoint(positions[i])); } } return(f); }
public void drawDesign(CScriptFEMM femm) { CFace face = null; foreach (CNode node in NodeList) { if (node.GetType().BaseType.Name == "CParts") { CParts nodeParts = (CParts)node; face = nodeParts.Face; if (null != face) { nodeParts.Face.drawFace(femm, nodeParts.MovingPart); } else { CNotice.printTraceID("YATT1"); } } } femm.zoomFit(); }
public static CSolid ReduceSolid(Solid A) { CSolid s = new CSolid(); s.faces = new List <CFace>(); s.vertices = new List <CPoint>(); foreach (Face a in A.faces) { if (a.isPlanar()) { CFace ca = new CFace(); List <Point> aPoints = a.GetPoints(); ca.points = new int[aPoints.Count]; ca.solid = s; for (int i = 0; i < aPoints.Count; ++i) { int index = s.vertices.FindIndex(x => x.position == aPoints[i].position); if (index == -1) { s.vertices.Add(new CPoint(aPoints[i])); ca.points[i] = s.vertices.Count - 1; } else { ca.points[i] = index; } } s.faces.Add(ca); } else { List <Point> aPoints = a.GetPoints(); for (int i = 0; i < aPoints.Count; ++i) { int index = s.vertices.FindIndex(x => x.position == aPoints[i].position); if (index == -1) { s.vertices.Add(new CPoint(aPoints[i])); } } for (int i = 0; i < a.subTriangles.Count; i += 3) { CFace ct = new CFace(); ct.solid = s; ct.points = new int[] { s.vertices.FindIndex(x => x.position == a.subTriangles[i]), s.vertices.FindIndex(x => x.position == a.subTriangles[i + 1]), s.vertices.FindIndex(x => x.position == a.subTriangles[i + 2]) }; s.faces.Add(ct); } } } return(s); }
public bool isDesignShapeOK(double dStroke = 0) { CFace face = null; bool bError = false; CParts nodeParts = null; // Moving Part 를 Stroke 만큼 이동시킨다. foreach (CNode node in NodeList) { if (node.GetType().BaseType.Name == "CParts") { nodeParts = (CParts)node; if (nodeParts.MovingPart == EMMoving.MOVING) { face = nodeParts.Face; face.BasePoint.m_dY = face.BasePoint.m_dY + dStroke; } } } if (isIntersectedAllLines() == true) { CNotice.noticeWarningID("LCBP"); bError = true; } if (isContactedMovingParts() == true) { CNotice.noticeWarningID("IHOT"); bError = true; } // Moving Part 를 Stroke 만큼 복원 시킨다. foreach (CNode node in NodeList) { if (node.GetType().BaseType.Name == "CParts") { nodeParts = (CParts)node; if (nodeParts.MovingPart == EMMoving.MOVING) { face = nodeParts.Face; face.BasePoint.m_dY = face.BasePoint.m_dY - dStroke; } } } if (bError == true) { return(false); } else { return(true); } }
private bool isContactedMovingParts() { List <CLine> listMovingPartLines = new List <CLine>(); List <CLine> listFixedPartLines = new List <CLine>(); List <CLine> listAbsoluteLine = null; CFace face = null; foreach (CNode node in NodeList) { if (node.GetType().BaseType.Name == "CParts") { CParts nodeParts = (CParts)node; face = nodeParts.Face; if (null != face) { listAbsoluteLine = face.AbsoluteLineList; if (nodeParts.MovingPart == EMMoving.MOVING) { /// Moving Part 라인들을 하나의 Line List 에 담는다. foreach (CLine line in listAbsoluteLine) { listMovingPartLines.Add(line); } } else { /// Moving Part 라인들을 하나의 Line List 에 담는다. foreach (CLine line in listAbsoluteLine) { listFixedPartLines.Add(line); } } } } } CShapeTools shapeTools = new CShapeTools(); for (int i = 0; i < listMovingPartLines.Count - 1; i++) { for (int j = i + 1; j < listFixedPartLines.Count; j++) { if (true == shapeTools.isContacted(listMovingPartLines[i], listFixedPartLines[j])) { return(true); } } } return(false); }
public void setBoundary(CScriptFEMM femm, double dMeshSizePercent, double dPlusMovingStroke, double dMinusMovingStroke) { const int iPaddingPercent = 200; double minX, minY, maxX, maxY; minX = minY = maxX = maxY = 0; this.getModelMinMaxX(ref minX, ref maxX); this.getModelMinMaxY(ref minY, ref maxY); double lengthX = Math.Abs(maxX - minX); double lengthY = Math.Abs(maxY - minY); // MeshSizePercent 에 문제가 있으면 1% 로 초기화 한다. if (dMeshSizePercent <= 0) { dMeshSizePercent = 1; } // Mesh Size 는 길이단위이기 때문에 면적을 루트 취한 값과 곱하고 있다. double dMeshSize = Math.Sqrt(this.calcShapeModelArea()) * dMeshSizePercent / 100.0f; double padLengthX = lengthX * iPaddingPercent / 100.0f; double padLengthY = lengthY * iPaddingPercent / 100.0f; /// - 긴방향의 길이로 Pad 량을 결정한다. /// - 100.0f 는 Percent 를 배수로 환산한다. double padLength = (padLengthX > padLengthY) ? padLengthX : padLengthY; CFace face = new CFace(); /// 외부 Region 을 생성 및 경계조건을 부여한다. /// - X min 값 : 0 /// - Mesh : AutoMesh face.setOutsideBoundary(femm, 0, maxY + padLength + dPlusMovingStroke, maxX + padLength, minY - padLength + dMinusMovingStroke, 0); /// 내부 Region 은 경계조건과 상관없이 메쉬만를 위해 추가하였다. /// 내부 Region 의 메쉬 크기는 기본 메쉬의 3배로 설정한다. const double dRatioRegion = 5.0f; /// 내부 Region 을 생성한다. /// - X min 값 : 0 /// - Mesh : 지정메쉬 * 3.0f face.setInsideRegion(femm, 0, maxY + padLengthY / dRatioRegion + dPlusMovingStroke, maxX + padLengthX / dRatioRegion, minY - padLengthY / dRatioRegion + dMinusMovingStroke, dMeshSize * 3.0f); }
public static Vector3[] DePolyTransform(Vector3[] U, CFace poly) { Vector3 a = poly.solid.vertices[poly.points[0]].position; Vector3 b = poly.solid.vertices[poly.points[1]].position; Vector3 c = poly.solid.vertices[poly.points[poly.points.Length - 1]].position; Vector3 X = (b - a).normalized; Vector3 Y = Vector3.Cross(X, c - a).normalized; Vector3 Z = Vector3.Cross(Y, X); Vector3[] V = new Vector3[U.Length]; for (int i = 0; i < U.Length; ++i) { V[i] = a + U[i].x * X + U[i].y * Y + U[i].z * Z; } return(V); }
private bool isIntersectedAllLines() { List <CLine> listLineAll = new List <CLine>(); List <CLine> listAbsoluteLine = null; CFace face = null; foreach (CNode node in NodeList) { if (node.GetType().BaseType.Name == "CParts") { CParts nodeParts = (CParts)node; face = nodeParts.Face; if (null != face) { listAbsoluteLine = face.AbsoluteLineList; /// 모든 라인들을 하나의 Line List 에 담는다. foreach (CLine line in listAbsoluteLine) { listLineAll.Add(line); } } } } CShapeTools shapeTools = new CShapeTools(); for (int i = 0; i < listLineAll.Count - 1; i++) { for (int j = i + 1; j < listLineAll.Count; j++) { if (true == shapeTools.isIntersected(listLineAll[i], listLineAll[j])) { return(true); } } } return(false); }
public static Vector3[] PolyTransform(Vector3[] V, CFace poly) { Vector3 a = poly.solid.vertices[poly.points[0]].position; Vector3 b = poly.solid.vertices[poly.points[1]].position; Vector3 c = poly.solid.vertices[poly.points[poly.points.Length - 1]].position; Vector3 X = (b - a).normalized; Vector3 Y = Vector3.Cross(X, c - a).normalized; Vector3 Z = Vector3.Cross(Y, X); Vector3[] U = new Vector3[V.Length]; for (int i = 0; i < V.Length; ++i) { U[i] = new Vector3(Vector3.Dot(V[i] - a, X), Vector3.Dot(V[i] - a, Y), Vector3.Dot(V[i] - a, Z)); } return(U); }
public static List <List <Vector3> > CrossSection(CSolid B, CFace a) { Vector3[] bTrans = new Vector3[B.vertices.Count]; Vector3[] aTrans = new Vector3[a.points.Length]; for (int i = 0; i < a.points.Length; ++i) { aTrans[i] = a.solid.vertices[a.points[i]].position; } for (int i = 0; i < B.vertices.Count; ++i) { bTrans[i] = B.vertices[i].position; } aTrans = PolyTransform(aTrans, a); bTrans = PolyTransform(bTrans, a); List <List <Vector3> > edges = new List <List <Vector3> >(); float epsilonSquared = 0.00001f; foreach (CFace b in B.faces) { List <Vector3> intersections = new List <Vector3>(); for (int i = 0; i < b.points.Length; ++i) { int j = (i + 1) % b.points.Length; int pi = b.points[i]; int pj = b.points[j]; if (Mathf.Sign(bTrans[pi].y) != Mathf.Sign(bTrans[pj].y)) { float t = -bTrans[pi].y / (bTrans[pj].y - bTrans[pi].y); intersections.Add(bTrans[pi] + (bTrans[pj] - bTrans[pi]) * t); } } if (intersections.Count > 1) { for (int i = intersections.Count - 1; i >= 0; --i) { for (int j = 0; j < i; ++j) { if ((intersections[j] - intersections[i]).sqrMagnitude <= epsilonSquared) { intersections.RemoveAt(i); i = Mathf.Min(i, intersections.Count - 1); } } } } if (intersections.Count > 1) { Vector3 edgeDir = intersections[intersections.Count - 1] - intersections[0]; intersections.Sort((x, y) => (int)Mathf.Sign(Vector3.Dot(y - x, edgeDir))); for (int i = 0; i < intersections.Count / 2; ++i) { List <Vector3> edge = new List <Vector3>(); edge.Add(intersections[i * 2]); edge.Add(intersections[i * 2 + 1]); edges.Add(edge); } } else if (intersections.Count == 1) { List <Vector3> edge = new List <Vector3>(); edge.Add(intersections[0]); edges.Add(edge); } } for (int i = edges.Count - 1; i >= 0; --i) { for (int j = 0; j < edges.Count; ++j) { if (i == j) { continue; } if ((edges[j][edges[j].Count - 1] - edges[i][0]).sqrMagnitude <= epsilonSquared) { for (int k = 1; k < edges[i].Count; ++k) { edges[j].Add(edges[i][k]); } edges[i].Clear(); edges.RemoveAt(i); break; } else if ((edges[j][edges[j].Count - 1] - edges[i][edges[i].Count - 1]).sqrMagnitude <= epsilonSquared) { for (int k = edges[i].Count - 2; k >= 0; --k) { edges[j].Add(edges[i][k]); } edges[i].Clear(); edges.RemoveAt(i); break; } else if ((edges[j][0] - edges[i][edges[i].Count - 1]).sqrMagnitude <= epsilonSquared) { for (int k = edges[i].Count - 2; k >= 0; --k) { edges[j].Insert(0, edges[i][k]); } edges[i].Clear(); edges.RemoveAt(i); break; } else if ((edges[j][0] - edges[i][0]).sqrMagnitude <= epsilonSquared) { for (int k = 1; k < edges[i].Count - 1; ++k) { edges[j].Insert(0, edges[i][k]); } edges[i].Clear(); edges.RemoveAt(i); break; } } } for (int i = edges.Count - 1; i >= 0; --i) { if (edges[i].Count < 3) { edges.RemoveAt(i); } else if ((edges[i][edges[i].Count - 1] - edges[i][0]).sqrMagnitude <= epsilonSquared) { edges[i].RemoveAt(edges[i].Count - 1); } } return(edges); }
public static Solid Clip(Solid A, Solid B, ClipMode mode) { List <CFace> Ai, Ax, Ao, Bi, Bx, Bo; CSolid Ac = ReduceSolid(A); CSolid Bc = ReduceSolid(B); //Divvy(Ac, Bc, out Ai, out Ax, out Ao); //Divvy(Bc, Ac, out Bi, out Bx, out Bo); Ai = new List <CFace>(); Ao = new List <CFace>(); Bi = new List <CFace>(); Bo = new List <CFace>(); foreach (CFace a in Ac.faces) { Vector3[] p = PolyTransform(a.GetVerts(), a); List <List <Vector3> > cross = CrossSection(Bc, a); foreach (List <Vector3> ql in cross) { Vector3[] q = ql.ToArray(); List <Vector3[]> pi, po; Clip2D(p, q, out pi, out po); foreach (Vector3[] poly in pi) { Ai.Add(Ac.MapFace(DePolyTransform(poly, a))); } foreach (Vector3[] poly in po) { Ao.Add(Ac.MapFace(DePolyTransform(poly, a))); } } if (cross.Count == 0) { if (B.ContainsPoint(Ac.vertices[a.points[0]].position)) { Ai.Add(a); } else { Ao.Add(a); } } } foreach (CFace b in Bc.faces) { Vector3[] p = PolyTransform(b.GetVerts(), b); List <List <Vector3> > cross = CrossSection(Ac, b); foreach (List <Vector3> ql in cross) { Vector3[] q = ql.ToArray(); List <Vector3[]> pi, po; Clip2D(p, q, out pi, out po); foreach (Vector3[] poly in pi) { Bi.Add(Bc.MapFace(DePolyTransform(poly, b))); } foreach (Vector3[] poly in po) { Bo.Add(Bc.MapFace(DePolyTransform(poly, b))); } } if (cross.Count == 0) { if (A.ContainsPoint(Bc.vertices[b.points[0]].position)) { Bi.Add(b); } else { Bo.Add(b); } } } //Set up merged CSolid CSolid Cc; Cc.vertices = new List <CPoint>(); Cc.faces = new List <CFace>(); int ACount = Ac.vertices.Count; Cc.vertices.AddRange(Ac.vertices); Cc.vertices.AddRange(Bc.vertices); //find points that are probably the same int[] map = new int[Cc.vertices.Count]; float epsilon = 0.005f; for (int i = 0; i < Cc.vertices.Count; ++i) { map[i] = -1; } for (int i = Cc.vertices.Count - 1; i >= 0; --i) { for (int j = 0; j <= i; ++j) { if (Vector3.Distance(Cc.vertices[i].position, Cc.vertices[j].position) < epsilon) { if (Cc.vertices[i].id != -1) { Cc.vertices[j].SetId(Cc.vertices[i].id); } map[i] = j; break; } } } //Add verts to merged CSolid if (mode == ClipMode.Subtract) { foreach (CFace f in Ao) { for (int i = 0; i < f.points.Length; ++i) { f.points[i] = map[f.points[i]]; } } Cc.faces.AddRange(Ao); foreach (CFace f in Bi) { for (int i = 0; i < f.points.Length; ++i) { f.points[i] = map[f.points[i] + ACount]; } } Cc.faces.AddRange(Bi); } else if (mode == ClipMode.Add) { //Merge A and B into C, using faces Ao, Bi, adding to point indices of Bi respectively (TODO) } else if (mode == ClipMode.Intersect) { //Merge A and B into C, using faces Ai, Bi, adding to point indices of Bi respectively (TODO) } //Find used vertices bool[] used = new bool[Cc.vertices.Count]; foreach (CFace f in Cc.faces) { foreach (int i in f.points) { used[i] = true; } } //Map duplicate points, create new points, delete unused points Point[] points = new Point[Cc.vertices.Count]; //Sparse Array Dictionary <int, Edge>[] edgeTo = new Dictionary <int, Edge> [Cc.vertices.Count]; //Sparse grid for (int i = 0; i < Cc.vertices.Count; ++i) { if (used[i]) { if (map[i] == i) { points[i] = Cc.vertices[i].id == -1 ? new Point(Cc.vertices[i].position) : DCGBase.all[Cc.vertices[i].id] as Point; Cc.vertices[i].SetId(points[i].elementID); edgeTo[i] = new Dictionary <int, Edge>(); } } else { if (Cc.vertices[i].id != -1) { DCGBase.all[Cc.vertices[i].id].Remove(); } } } //Nuke A and B foreach (Point p in A.getPoints()) { for (int i = p.edges.Count - 1; i >= 0; --i) { p.edges[i].Remove(); } } foreach (Point p in B.getPoints()) { for (int i = p.edges.Count - 1; i >= 0; --i) { p.edges[i].Remove(); } } //Create new edges/faces in DCG Face[] faces = new Face[Cc.faces.Count]; for (int i = 0; i < Cc.faces.Count; ++i) { CFace f = Cc.faces[i]; Edge[] edges = new Edge[f.points.Length]; Debug.Log(f.points.Length); for (int j = 0; j < f.points.Length; ++j) { int k = (j + 1) % f.points.Length; int pk = f.points[k]; int pj = f.points[j]; bool kcj = edgeTo[pk].ContainsKey(pj); bool jck = edgeTo[pj].ContainsKey(pk); if (jck) { edges[j] = edgeTo[pj][pk]; if (!kcj) { edgeTo[pk].Add(pj, edges[j]); } } else if (kcj) { edges[j] = edgeTo[pk][pj]; if (!jck) { edgeTo[pj].Add(pk, edges[j]); } } else { edges[j] = new Edge(points[pj], points[pk]); //if (!jck) edgeTo[pj].Add(pk, edges[j]); //if (!kcj) edgeTo[pk].Add(pj, edges[j]); } //Debug.DrawLine(edges[j].points[0].position, edges[j].points[1].position, new Color(Random.value, Random.value, Random.value), 1000, false); } //Debug.Log(edges.Length); faces[i] = new Face(new List <Edge>(edges)); } //Create new solid from C return(new Solid(new List <Face>(faces))); //return new Solid(); //TODO eventually, if we have time: //Relate generated Faces and Edges to existing Faces and Edges, in order to reduce new objects being created or to copy materials/etc. }
// 코일에 대한 문자열 라인을 넘겨 받아서 코일 객체를 초기화 한다. public bool readObject(List <string> listStringLines) { CReadFile readFile = new CReadFile(); string strTemp; string[] arrayString; List <string> listInformationLines = new List <string>(); List <string> listShapeLines = new List <string>(); bool bShapeLine = false; if (KindKey != EMKind.COIL) { CNotice.printLogID("YATT7"); return(false); } try { // Shape 라인과 정보 라인을 분리한다. foreach (string strLine in listStringLines) { if (readFile.isEndLine(strLine) == "Shape") { bShapeLine = false; } if (bShapeLine == true) { listShapeLines.Add(strLine); } else { if (readFile.isBeginLine(strLine) == "Shape") { bShapeLine = true; } else { listInformationLines.Add(strLine); } } } // 정보 라인을 처리한다. foreach (string strLine in listInformationLines) { strTemp = strLine.Trim('\t'); arrayString = strTemp.Split('='); switch (arrayString[0]) { // CNode case "NodeName": NodeName = arrayString[1]; break; case "KindKey": KindKey = (EMKind)Enum.Parse(typeof(EMKind), arrayString[1]); break; // CParts case "MovingParts": MovingPart = (EMMoving)Enum.Parse(typeof(EMMoving), arrayString[1]); break; // CCoil case "Material": if (CMaterialListInFEMM.isCoilWIreInList(arrayString[1]) == true) { m_strMaterialName = arrayString[1]; } else { // 현재의 버전에서 사용할 수 없는 재질이 존재한다면 공백으로 처리하고 // 동작 중에 공백을 사용해서 재질이 초기화 되지 않음을 확인한다. m_strMaterialName = ""; } break; case "CurrentDirection": CurrentDirection = (EMCurrentDirection)Enum.Parse(typeof(EMCurrentDirection), arrayString[1]); break; case "Turns": Turns = Convert.ToInt16(arrayString[1]); break; case "Resistance": Resistance = Convert.ToDouble(arrayString[1]); break; case "Resistance_20": Resistance_20 = Convert.ToDouble(arrayString[1]); break; case "Layers": Layers = Convert.ToInt16(arrayString[1]); break; case "TurnsOfOneLayer": TurnsOfOneLayer = Convert.ToInt16(arrayString[1]); break; case "CoilWireGrade": CoilWireGrade = (EMCoilWireGrade)Enum.Parse(typeof(EMCoilWireGrade), arrayString[1]); break; case "InnerDiameter": InnerDiameter = Convert.ToDouble(arrayString[1]); break; case "OuterDiameter": OuterDiameter = Convert.ToDouble(arrayString[1]); break; case "Height": Height = Convert.ToDouble(arrayString[1]); break; case "CopperDiameter": CopperDiameter = Convert.ToDouble(arrayString[1]); break; case "WireDiameter": WireDiameter = Convert.ToDouble(arrayString[1]); break; case "Temperature": Temperature = Convert.ToDouble(arrayString[1]); break; case "HorizontalCoefficient": HorizontalCoefficient = Convert.ToDouble(arrayString[1]); break; case "VerticalCoefficient": VerticalCoefficient = Convert.ToDouble(arrayString[1]); break; case "ResistanceCoefficient": ResistanceCoefficient = Convert.ToDouble(arrayString[1]); break; default: break; } } // Shape 정보가 있는 경우만 m_face 를 생성하고 읽기 작업을 진행한다. if (listShapeLines.Count > 0) { m_face = new CFace(); m_face.readObject(listShapeLines); } } catch (Exception ex) { CNotice.printLog(ex.Message); return(false); } return(true); }
// 코일에 대한 문자열 라인을 넘겨 받아서 코일 객체를 초기화 한다. public bool readObject(List <string> listStringLines) { CReadFile readFile = new CReadFile(); string strTemp; string[] arrayString; List <string> listInformationLines = new List <string>(); List <string> listShapeLines = new List <string>(); bool bShapeLine = false; if (KindKey != EMKind.NON_KIND) { CNotice.printLog("NON_KIND 가 아닌 객체가 CNonKind 로 열리려고 한다."); return(false); } try { // Shape 라인과 정보 라인을 분리한다. foreach (string strLine in listStringLines) { if (readFile.isEndLine(strLine) == "Shape") { bShapeLine = false; } if (bShapeLine == true) { listShapeLines.Add(strLine); } else { if (readFile.isBeginLine(strLine) == "Shape") { bShapeLine = true; } else { listInformationLines.Add(strLine); } } } // 정보 라인을 처리한다. foreach (string strLine in listInformationLines) { strTemp = strLine.Trim('\t'); arrayString = strTemp.Split('='); /// 각 줄의 String 배열은 항상 2개이여야 한다. if (arrayString.Length != 2) { CNotice.printLog("Non-Kind 데이터에 문제가 있습니다."); return(false); } switch (arrayString[0]) { // CNode case "NodeName": NodeName = arrayString[1]; break; case "KindKey": KindKey = (EMKind)Enum.Parse(typeof(EMKind), arrayString[1]); break; // Non Kind 는 CNode 의 정보와 CShapParts 의 Face 정보만 필요하기 때문에 // 나머지 정보는 저장하지 않는다. // // CShapeParts //case "MovingParts": // MovingPart = (EMMoving)Enum.Parse(typeof(EMMoving), arrayString[1]); // break; default: break; } } // Shape 정보가 있는 경우만 m_face 를 생성하고 읽기 작업을 진행한다. if (listShapeLines.Count > 0) { m_face = new CFace(); if (m_face == null) { CNotice.printLogID("IIAT"); } else { m_face.readObject(listShapeLines); } } } catch (Exception ex) { CNotice.printLog(ex.Message); return(false); } return(true); }
// 코일에 대한 문자열 라인을 넘겨 받아서 코일 객체를 초기화 한다. public bool readObject(List <string> listStringLines) { CReadFile readFile = new CReadFile(); string strTemp; string[] arrayString; List <string> listInformationLines = new List <string>(); List <string> listShapeLines = new List <string>(); bool bShapeLine = false; if (KindKey != EMKind.STEEL) { CNotice.printLogID("YATT6"); return(false); } try { // Shape 라인과 정보 라인을 분리한다. foreach (string strLine in listStringLines) { if (readFile.isEndLine(strLine) == "Shape") { bShapeLine = false; } if (bShapeLine == true) { listShapeLines.Add(strLine); } else { if (readFile.isBeginLine(strLine) == "Shape") { bShapeLine = true; } else { listInformationLines.Add(strLine); } } } // 정보 라인을 처리한다. foreach (string strLine in listInformationLines) { strTemp = strLine.Trim('\t'); arrayString = strTemp.Split('='); if (arrayString.Length != 2) { CNotice.noticeWarningID("TIAP5"); return(false); } switch (arrayString[0]) { // CNode case "NodeName": NodeName = arrayString[1]; break; case "KindKey": KindKey = (EMKind)Enum.Parse(typeof(EMKind), arrayString[1]); break; // CParts case "MovingParts": MovingPart = (EMMoving)Enum.Parse(typeof(EMMoving), arrayString[1]); break; // CSteel case "Material": if (CMaterialListInFEMM.isSteelInList(arrayString[1]) == true) { m_strMaterialName = arrayString[1]; } else { // 현재의 버전에서 사용할 수 없는 재질이 존재한다면 공백으로 처리하고 // 동작 중에 공백을 사용해서 재질이 초기화 되지 않음을 확인한다. m_strMaterialName = ""; } break; default: break; } } // Shape 정보가 있는 경우만 m_face 를 생성하고 읽기 작업을 진행한다. if (listShapeLines.Count > 0) { m_face = new CFace(); m_face.readObject(listShapeLines); } } catch (Exception ex) { CNotice.printLog(ex.Message); return(false); } return(true); }
private ClipperResponse ClipFace(CFace face, out CFace newFace) { newFace = null; var numInside = 0; var numOutside = 0; foreach (var vertId in face.VertIdxs) { if (CVertices[vertId].Distance > 0.0f) { numInside++; } else if (CVertices[vertId].Distance < 0.0f) { numOutside++; } } if (numOutside == 0) { return(ClipperResponse.NoneClipped); } if (numInside == 0) { return(ClipperResponse.AllClipped); } var count = 0; var newPoly = new VertCoord[4]; var prevIdx = face.VertIdxs.Length - 1; for (var idx = 0; idx < face.VertIdxs.Length; idx++) { var vertIdx0 = face.VertIdxs[prevIdx]; var vertIdx1 = face.VertIdxs[idx]; var vert0 = CVertices[vertIdx0]; var vert1 = CVertices[vertIdx1]; // vert1 outside if (vert1.Distance < 0.0f) { // vert0 inside if (vert0.Distance > 0.0f) { var time = vert0.Distance / (vert0.Distance - vert1.Distance); var newPoint = (1.0f - time) * vert0.Point + time * vert1.Point; var newIdx = AddOrGetVertex(newPoint); CVertices[newIdx].IsVisible = true; newPoly[count++] = newIdx; } } else { // vert0 outside, vert1 inside if (vert1.Distance > 0.0f && vert0.Distance < 0.0f) { var time = vert1.Distance / (vert1.Distance - vert0.Distance); var newPoint = (1.0f - time) * vert1.Point + time * vert0.Point; var newIdx = AddOrGetVertex(newPoint); CVertices[newIdx].IsVisible = true; newPoly[count++] = newIdx; } newPoly[count++] = vertIdx1; } prevIdx = idx; } if (count == 3) { for (var i = 0; i < 3; i++) { face.VertIdxs[i] = newPoly[i]; } return(ClipperResponse.SomeClipped); } // Re-triangulate the quadrangle var newFaces = ReTriangulate(newPoly); face.VertIdxs = new[] { newFaces[0], newFaces[1], newFaces[2] }; newFace = new CFace(new[] { newFaces[3], newFaces[4], newFaces[5] }); return(ClipperResponse.SomeClipped); }
protected bool readShapeInformation(List <string> listShapeLines) { string strTemp; string[] arrayString; try { // Shape 정보가 있는 경우만 m_face 를 생성하고 읽기 작업을 진행한다. if (listShapeLines.Count > 0) { m_face = new CFace(); } else { return(false); } CPoint point = null; // 형상 라인을 처리한다. foreach (string strLine in listShapeLines) { strTemp = strLine.Trim('\t'); arrayString = strTemp.Split('='); /// 각 줄의 String 배열은 항상 2개이여야 한다. if (arrayString.Length != 2) { CNotice.noticeWarningID("TIAP5"); return(false); } if (m_face == null) { CNotice.printTraceID("IIAT"); return(false); } switch (arrayString[0]) { case "BasePointX": m_face.BasePoint.m_dX = Double.Parse(arrayString[1]); break; case "BasePointY": m_face.BasePoint.m_dY = Double.Parse(arrayString[1]); break; case "FaceType": m_face.FaceType = (EMFaceType)Enum.Parse(typeof(EMFaceType), arrayString[1]); break; case "PointX": // PointX 키워드를 만날때 새로운 CPoint 생성하고, // ArcDriction 키워드를 만날때 생성된 CPoint 를 Face 에 추가한다. // 따라서 저장될때 X, Y, LineKind, ArcDriction 의 순서로 꼭 저장 되어야 한다. point = new CPoint(); point.m_dX = Double.Parse(arrayString[1]); break; case "PointY": if (point != null) { point.m_dY = Double.Parse(arrayString[1]); } else { CNotice.noticeWarningID("YCWX"); return(false); } break; case "LineKind": if (point != null) { point.m_emLineKind = (EMLineKind)Enum.Parse(typeof(EMLineKind), arrayString[1]); } else { CNotice.noticeWarningID("TIAP9"); return(false); } break; case "ArcDriction": if (point != null) { point.m_emDirectionArc = (EMDirectionArc)Enum.Parse(typeof(EMDirectionArc), arrayString[1]); } else { CNotice.noticeWarningID("TIAP10"); return(false); } // ArcDriction 에서 point 을 저장한다. m_face.addPoint(point); break; default: break; } } } catch (Exception ex) { CNotice.printTrace(ex.Message); return(false); } return(true); }
// 코일에 대한 문자열 라인을 넘겨 받아서 코일 객체를 초기화 한다. public bool readObject(List <string> listStringLines) { CReadFile readFile = new CReadFile(); string strTemp; string[] arrayString; List <string> listInformationLines = new List <string>(); List <string> listShapeLines = new List <string>(); bool bShapeLine = false; if (KindKey != EMKind.MAGNET) { CNotice.printLogID("YATT5"); return(false); } try { // Shape 라인과 정보 라인을 분리한다. foreach (string strLine in listStringLines) { if (readFile.isEndLine(strLine) == "Shape") { bShapeLine = false; } if (bShapeLine == true) { listShapeLines.Add(strLine); } else { if (readFile.isBeginLine(strLine) == "Shape") { bShapeLine = true; } else { listInformationLines.Add(strLine); } } } // 정보 라인을 처리한다. foreach (string strLine in listInformationLines) { strTemp = strLine.Trim('\t'); arrayString = strTemp.Split('='); if (arrayString.Length != 2) { CNotice.noticeWarningID("TIAP4"); return(false); } switch (arrayString[0]) { // CNode case "NodeName": NodeName = arrayString[1]; break; case "KindKey": KindKey = (EMKind)Enum.Parse(typeof(EMKind), arrayString[1]); break; // CParts case "MovingParts": MovingPart = (EMMoving)Enum.Parse(typeof(EMMoving), arrayString[1]); break; // CMagnet case "Material": m_strMaterialName = arrayString[1]; // FEMM (21Apr2019)에서 NdFeB 40 MGOe 빠져 있어서 호환이 되지 않아 강제로 N40 으로 변경한다. // 추후에 FEMM 에 NdFeB 40 MGOe 가 Legacy 로 추가되면 아래의 코드를 삭제하라. if (CProgramFEMM.getYearFEMM() >= 2019) { if (m_strMaterialName == "NdFeB 40 MGOe") { m_strMaterialName = "N40"; } } if (CMaterialListInFEMM.isMagnetlInList(m_strMaterialName) == false) { // 현재의 버전에서 사용할 수 없는 재질이 존재한다면 공백으로 처리하고 // 동작 중에 공백을 사용해서 재질이 초기화 되지 않음을 확인한다. m_strMaterialName = ""; } break; case "MagnetDirection": emMagnetDirection = (EMMagnetDirection)Enum.Parse(typeof(EMMagnetDirection), arrayString[1]); break; default: break; } } // Shape 정보가 있는 경우만 m_face 를 생성하고 읽기 작업을 진행한다. if (listShapeLines.Count > 0) { m_face = new CFace(); m_face.readObject(listShapeLines); } } catch (Exception ex) { CNotice.printLog(ex.Message); return(false); } return(true); }