/// <summary> /// Converts 'value' from internal units (which are Metric) to Standard (Feet) if Engine unitMode is set /// to Standard. If 'value' is not a numeric type, an exception may be thrown. /// Does Not modify 'value'. /// </summary> public static float GetExternalValue(BendParameter param) { if (Engine.unitType == Units.Type.Standard) { return((float)param.value * Units.k_MToFt); } return((float)param.value); }
/*################################## * * Public Functions * ###################################*/ /// <summary> /// Links this Bend Input Screen to a Bend and Sets up Screen Appropriately /// </summary> public override void Link(IModel model) { if (!m_HasInitialized) { Debug.LogError("BendInputScreen: Link() Screen must first be Initialized."); return; } if (m_Bend != null) { // Unregister Listeners on Previous Bend m_Bend.onEvent.RemoveListener(ListenerBend); } Bend bend = (Bend)model; m_Bend = bend; m_Bend.onEvent.AddListener(ListenerBend); // Initialize Output View InitializeOutput(); RectTransform scrollerContent = bendParameterScroller.content; RectTransform bendParamPrefab; UIBendParameter uiBendParam; BendParameter bendParam; bendParameterScroller.ClearContent(); // Set up Bend Input Parameter View for (int i = 0; i < bend.inputParameters.Count; ++i) { bendParam = bend.inputParameters[i]; bendParamPrefab = Instantiate(bendParameterPrefab); bendParamPrefab.SetParent(scrollerContent, false); uiBendParam = bendParamPrefab.GetComponent <UIBendParameter>(); uiBendParam.Set(bendParam.type, BendParameter.GetStringValue(bendParam.name), i); uiBendParam.onClick = DisplayWidget; if (i == 0) { // Set 1st Parameter as Selected uiBendParam.button.Select(); } } bendParameterScroller.Layout(); // Set up Help Widget bendParamPrefab = Instantiate(bendParameterPrefab); bendParamPrefab.SetParent(scrollerContent, false); uiBendParam = bendParamPrefab.GetComponent <UIBendParameter>(); uiBendParam.SetAsHelp(); uiBendParam.onClick = DisplayHelpWidget; // Display 1st Parameter Widget m_ActiveParameter = -1; DisplayWidget(0); }
public void SetHighlightables(List <BendParameter> highlightables) { m_highlightables = highlightables; // Clear previous Parameters var content = parameterScroller.content; for (int i = 0; i < content.childCount; ++i) { Destroy(content.GetChild(i).gameObject); } if (highlightables.Count == 0) { message.text = k_UnAvailableMessage; return; } else { message.text = k_AvailableMessage; } // Populate Parameter view RectTransform scrollerContent = parameterScroller.content; RectTransform paramPrefab; Button paramButton; Text paramText; Vector2 nextPos = parameterPrefab.anchoredPosition; Vector2 size = parameterPrefab.rect.size; for (var i = 0; i < m_highlightables.Count; ++i) { var param = m_highlightables[i]; var index = i; // Instantiate next paramPrefab = Instantiate(parameterPrefab); // Position, Format and Listen paramButton = paramPrefab.GetComponent <Button>(); paramButton.onClick.AddListener(() => { OnParameterClick(index); }); paramText = paramPrefab.GetComponent <Text>(); paramText.text = BendParameter.GetStringValue(param.name); paramText.color = Color.black; paramPrefab.SetParent(scrollerContent, false); paramPrefab.anchoredPosition = nextPos; paramPrefab.gameObject.SetActive(true); nextPos.y -= size.y; } }
/// <summary> /// Sets the current BendParameter to be highlighted. /// Assumes the BendParameter is a highlightable type /// </summary> public void SetHighlight(BendParameter highlightable) { m_Highlight = highlightable; if (highlightable == null) { onEvent.Invoke(EventType.HighlightOff); } else { onEvent.Invoke(EventType.HighlightOn); } }
/// <summary> /// Returns value of Parameter formatted as a string, returned in current display unit type (Feet or Meters) /// </summary> /// <param name="bendParam"></param> /// <returns></returns> public static string GetFormattedValue(BendParameter bendParam) { switch (bendParam.type) { case EBendParameterType.FloatAngle: return(bendParam.value.ToString()); case EBendParameterType.Float: return(Units.Format(Engine.unitType, Engine.outputRulerUnit, GetExternalValue((float)bendParam.value))); case EBendParameterType.Integer: return(bendParam.value.ToString()); case EBendParameterType.StringEnum: StringEnum se = (StringEnum)bendParam.valueObject; return(se.ToStringValue((int)bendParam.value)); } return(""); }
private void InitializeOutput() { // Init Output View TextColumns.TextPair textPair; BendParameter bendParam; int pinput = 0; m_EnabledParameterMask = 0; m_OutputText.Clear(); // Input Parameters for (int p = 0; p < m_Bend.inputParameters.Count; ++p) { bendParam = m_Bend.inputParameters[p]; textPair = new TextColumns.TextPair(); textPair.left = "<b>" + BendParameter.GetStringValue(bendParam.name) + ":</b> "; textPair.right = "<color=#" + bendParam.colorHexString + ">" + BendParameter.GetFormattedValue(bendParam) + "</color>"; m_OutputText.Write(textPair); } pinput = m_Bend.inputParameters.Count; // Output Parameters (FF1800FF, EA75FF) for (int p = 0; p < m_Bend.outputParameters.Count; ++p) { bendParam = m_Bend.outputParameters[p]; if (bendParam.enabled) { m_EnabledParameterMask |= 1 << (pinput + p); textPair = new TextColumns.TextPair(); textPair.left = "<b>" + BendParameter.GetStringValue(bendParam.name) + ":</b> "; textPair.right = "<b><color=#" + bendParam.colorHexString + ">" + BendParameter.GetFormattedValue(bendParam) + "</color></b>"; m_OutputText.Write(textPair); } } //Debug.Log( "BendInputScreen: InitializeOutput() m_EnabledParameterMask: " + m_EnabledParameterMask + " Lines: " + m_OutputText.lineCount ); }
//-------------------------------------------------------------------------------------------------- void _FindFacesConnectedToBendSection(MakeContext context, TopoDS_Edge sharedEdge, BendParameter bendParams) { // Find connected section faces bendParams.ConnectedInSharedEdges[0] = sharedEdge; bendParams.ConnectedInFaces[0] = FaceAlgo.FindConnectedFace(context.SourceShape, bendParams.Faces[0], sharedEdge); var opEdge = bendParams.Faces[0].Edges().Find(e => !e.IsSame(sharedEdge) && !e.IsSame(bendParams.Edges[0]) && !e.IsSame(bendParams.Edges[1])); if (opEdge != null) { bendParams.ConnectedOutSharedEdges[0] = opEdge; bendParams.ConnectedOutFaces[0] = FaceAlgo.FindConnectedFace(context.SourceShape, bendParams.Faces[0], opEdge); } // Find the other connection edge TopoDS_Vertex sharedVtx1 = null; foreach (var edge in bendParams.Faces[1].Edges()) { var vtx = EdgeAlgo.FindSharedVertex(edge, sharedEdge); if (vtx != null) { // Get the other (not shared) vertex sharedVtx1 = edge.Vertices().Find(v => !v.IsSame(vtx)); break; } } TopoDS_Vertex sharedVtx2 = null; foreach (var edge in bendParams.Faces[2].Edges()) { var vtx = EdgeAlgo.FindSharedVertex(edge, sharedEdge); if (vtx != null) { // Get the other (not shared) vertex sharedVtx2 = edge.Vertices().Find(v => !v.IsSame(vtx)); break; } } TopoDS_Edge otherSharedEdge = null; foreach (var edge in bendParams.Faces[3].Edges()) { var vertices = edge.Vertices(); if (vertices.ContainsSame(sharedVtx1) && vertices.ContainsSame(sharedVtx2)) { otherSharedEdge = edge; break; } } if (otherSharedEdge == null) { return; } // Find connected section faces for the other edge bendParams.ConnectedOutSharedEdges[1] = otherSharedEdge; bendParams.ConnectedInFaces[1] = FaceAlgo.FindConnectedFace(context.SourceShape, bendParams.Faces[3], otherSharedEdge); var otherOpEdge = bendParams.Faces[3].Edges().Find(e => !e.IsSame(otherSharedEdge) && !e.IsSame(bendParams.Edges[2]) && !e.IsSame(bendParams.Edges[3])); if (otherOpEdge != null) { bendParams.ConnectedOutSharedEdges[1] = otherOpEdge; bendParams.ConnectedOutFaces[1] = FaceAlgo.FindConnectedFace(context.SourceShape, bendParams.Faces[3], otherOpEdge); } }
//-------------------------------------------------------------------------------------------------- bool _IsFaceOfBendSection(TopoDS_Face face, BendParameter bendParams) { if (bendParams == null) { bendParams = new BendParameter(); // Temporary usage } // Each face of a bend section has two circular edges var edges = face.Edges(); var foundCircularEdges = 0; foreach (var edge in edges) { var edgeAdaptor = new BRepAdaptor_Curve(edge); if (edgeAdaptor.GetGeomType() == GeomAbs_CurveType.GeomAbs_Circle) { foundCircularEdges++; if (bendParams.Edges[0] == null) { bendParams.Edges[0] = edge; bendParams.Axes[0] = edgeAdaptor.Circle().Position(); bendParams.Radii[0] = edgeAdaptor.Circle().Radius(); bendParams.AngleRad = edgeAdaptor.LastParameter() - edgeAdaptor.FirstParameter(); } else { if (!bendParams.Axes[0].Axis.IsCoaxial(edgeAdaptor.Circle().Axis(), 0.01f, 0.001f) || !bendParams.AngleRad.IsEqual(edgeAdaptor.LastParameter() - edgeAdaptor.FirstParameter(), 0.01)) { return(false); // Circular edge with unproper parameters detected } if (bendParams.Edges[1] == null) { // Second edge of bend surface bendParams.Edges[1] = edge; bendParams.Axes[1] = edgeAdaptor.Circle().Position(); break; } // Additional edges, find free place for (int edgeIndex = 0; edgeIndex < bendParams.Edges.Length; edgeIndex++) { if (bendParams.Edges[edgeIndex] == null) { bendParams.Edges[edgeIndex] = edge; break; } if (bendParams.Edges[edgeIndex].IsSame(edge)) { break; } } if (!edgeAdaptor.Circle().Radius().IsEqual(bendParams.Radii[0], 0.000001)) { bendParams.Radii[1] = edgeAdaptor.Circle().Radius(); } } } } // Coaxial circle edges not found, this is not a bend section if (foundCircularEdges != 2) { return(false); } return(true); }
//-------------------------------------------------------------------------------------------------- /* * Determine if a face belongs to a bend section. To recognise a bend section, it must have the * following structure: * - Four faces, two of them planar (side faces) and two of them cylinder (top/bottom) * - All edges connecting these four faces must be circular * - All circles must have coaxial axes with only two different positions * - All circles must have one of two radii * * If a side face is detected, the iteration of faces should stop, but no section is built. * If a top/bottom face is detected, the whole section is recovered and all parameters are * determined. The faces are found by searching for faces which share the circular edges. * * This function is called recursively if one of the out-faces is also recognized * as part of a connected bend section. */ bool _AnalyzeBendSection(MakeContext context, TopoDS_Face baseFace, TopoDS_Edge sharedEdge, out Section section) { section = null; var bendParams = new BendParameter(); bendParams.Faces[0] = baseFace; if (!_IsFaceOfBendSection(baseFace, bendParams)) { return(false); } var faceAdaptor = new BRepAdaptor_Surface(baseFace); // Surface is flat, but two edges are of circle and coplanar if (faceAdaptor.GetGeomType() == GeomAbs_SurfaceType.GeomAbs_Plane) { // Ignore them for the moment, but sign them as bend section face return(true); } if (faceAdaptor.GetGeomType() != GeomAbs_SurfaceType.GeomAbs_Cylinder) { // Surface must be of type Cylinder, other are not supported currently return(false); } // Find side faces var facesForEdge0 = EdgeAlgo.FindAdjacentFaces(context.SourceShape, bendParams.Edges[0]); bendParams.Faces[1] = facesForEdge0.face1.IsSame(baseFace) ? facesForEdge0.face2 : facesForEdge0.face1; if (!_IsFaceOfBendSection(bendParams.Faces[1], bendParams)) { return(false); } var facesForEdge1 = EdgeAlgo.FindAdjacentFaces(context.SourceShape, bendParams.Edges[1]); bendParams.Faces[2] = facesForEdge1.face1.IsSame(baseFace) ? facesForEdge1.face2 : facesForEdge1.face1; if (!_IsFaceOfBendSection(bendParams.Faces[2], bendParams)) { return(false); } // Find fourth face var facesForEdge2 = EdgeAlgo.FindAdjacentFaces(context.SourceShape, bendParams.Edges[2]); var facesForEdge3 = EdgeAlgo.FindAdjacentFaces(context.SourceShape, bendParams.Edges[3]); if (facesForEdge2.face1.IsSame(facesForEdge3.face1) || facesForEdge2.face1.IsSame(facesForEdge3.face2)) { bendParams.Faces[3] = facesForEdge2.face1; } else if (facesForEdge2.face2.IsSame(facesForEdge3.face1) || facesForEdge2.face2.IsSame(facesForEdge3.face2)) { bendParams.Faces[3] = facesForEdge2.face2; } else { return(false); // fourth face not found } if (!_IsFaceOfBendSection(bendParams.Faces[3], bendParams)) { return(false); } // Create Section section = new Section(); section.Faces.AddRange(bendParams.Faces.Where(face => face != null)); section.BendParameter = bendParams; // Find connected faces _FindFacesConnectedToBendSection(context, sharedEdge, bendParams); // Check if the connected section is also an bend section if (bendParams.ConnectedOutFaces[0] != null && _AnalyzeBendSection(context, bendParams.ConnectedOutFaces[0], bendParams.ConnectedOutSharedEdges[0], out var connectedBendSection)) { if (connectedBendSection == null) { Messages.Error("A bend section is connected to another bend section with an perpendicular direction.", "To fix this, you need to add a small flange between these two bend sections."); } section.Children.Add(connectedBendSection); } else { section.Children.Add(new Section()); // Bend sections have exactly one connected section } return(true); }
private void ListenerHelp(BendParameter val) { m_Bend.SetHighlight(val); }
private void DisplayWidget(int id) { // Remove any active Highlighting m_Bend.SetHighlight(null); m_HelpWidget.GetComponentInChildren <BendHelp>().UnSelect(); // Don't reselect the same Widget if (m_ActiveParameter == id) { return; } // Disable current Widget if (m_ActiveWidget != null) { m_ActiveWidget.gameObject.SetActive(false); } m_ActiveParameter = id; BendParameter param = m_Bend.inputParameters[id]; EBendParameterType type = param.type; object[] range = BendParameter.GetRange(param.name); switch (type) { case EBendParameterType.FloatAngle: m_ActiveWidget = m_AngleWidget; m_ActiveWidget.gameObject.SetActive(true); AngleSlider ans = m_AngleWidget.GetComponentInChildren <AngleSlider>(); ans.SetRange((float)range[0], (float)range[1]); ans.value = (float)param.value; break; case EBendParameterType.Float: m_ActiveWidget = m_RulerWidget; m_ActiveWidget.gameObject.SetActive(true); MultiRulerSlider mr = m_RulerWidget.GetComponentInChildren <MultiRulerSlider>(); mr.SetRange((float)range[1]); mr.Set((float)param.value, false); break; case EBendParameterType.Integer: m_ActiveWidget = m_IntegerWidget; m_ActiveWidget.gameObject.SetActive(true); IntegerSlider ins = m_IntegerWidget.GetComponentInChildren <IntegerSlider>(); ins.SetRange((int)range[0], (int)range[1]); ins.SetName(BendParameter.GetStringValue(param.name)); ins.value = (int)param.value; break; case EBendParameterType.StringEnum: m_ActiveWidget = m_EnumWidget; m_ActiveWidget.gameObject.SetActive(true); EnumDropdown ed = m_EnumWidget.GetComponentInChildren <EnumDropdown>(); List <Dropdown.OptionData> enumList = ed.options; StringEnum se = (StringEnum)param.valueObject; int enumStart = (int)range[0]; int enumEnd = (int)range[1]; enumList.Clear(); for (int i = enumStart; i <= enumEnd; ++i) { enumList.Add(new EnumDropdown.EnumOptionData(se.ToStringValue(i), null, se.ToDescription(i))); } ed.value = (int)param.value; ed.Refresh(); break; default: throw new ArgumentException("BendInputScreen: DisplayWidget() Invalid type."); } }
/// <summary> /// Refresh Output View /// </summary> public void ListenerBend(Bend.EventType type) { if (type != Bend.EventType.Calculated) { return; } BendParameter bendParam; TextColumns.TextPair textPair; int enabledMask = 0; int line = 0; int pinput = 0; var textPairs = m_OutputText.GetLines(); // Assert no bitmask overflow Debug.Assert(m_Bend.inputParameters.Count + m_Bend.outputParameters.Count <= sizeof(int) * 8); // Input Parameters for (int p = 0; p < m_Bend.inputParameters.Count && p < textPairs.Count; ++p) { bendParam = m_Bend.inputParameters[p]; if (bendParam.enabled) { enabledMask |= 1 << (p); textPair = textPairs[line]; textPair.right = "<color=#" + bendParam.colorHexString + ">" + BendParameter.GetFormattedValue(bendParam) + "</color>"; textPairs[line] = textPair; line += 1; } } pinput = m_Bend.inputParameters.Count; // Output Parameters (FF1800FF, EA75FF) for (int p = 0; p < m_Bend.outputParameters.Count && line < textPairs.Count; ++p) { bendParam = m_Bend.outputParameters[p]; if (bendParam.enabled) { enabledMask |= 1 << (pinput + p); textPair = textPairs[line]; textPair.right = "<b><color=#" + bendParam.colorHexString + ">" + BendParameter.GetFormattedValue(bendParam) + "</color></b>"; textPairs[line] = textPair; line += 1; } } if (enabledMask != m_EnabledParameterMask) { InitializeOutput(); } else { m_OutputText.WriteLines(textPairs); } // Display any Alert Text if (!string.IsNullOrEmpty(m_Bend.alert)) { alertText.Set(m_Bend.alert); } else { alertText.Off(); } //Debug.Log( "UIBendInputScreen: ListenerBend() Output Refreshed." ); }