Files
wg_cpso/CPSO/Forms/62_Query/FrmQuery.cs
2026-03-25 18:20:24 +08:00

774 lines
37 KiB
C#

using CaeGlobals;
using CaeMesh;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
// ReSharper disable CheckNamespace
namespace CPSO.Forms
{
public partial class FrmQuery : UserControls.PrePoMaxChildForm
{
// Variables
private int _numOfNodesToSelect;
private double[][] _coorNodesToDraw;
private double[][] _coorLinesToDraw;
private Controller _controller;
// Callbacks
public Action<string> Form_WriteDataToOutput;
public Action<object, EventArgs> Form_RemoveAnnotations;
// Constructors
public FrmQuery()
{
InitializeComponent();
_numOfNodesToSelect = -1;
}
// Event handlers
private void lvQueries_MouseDown(object sender, MouseEventArgs e)
{
lvQueries.SelectedItems.Clear();
}
private void lvQueries_MouseUp(object sender, MouseEventArgs e)
{
}
private void lvQueries_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (lvQueries.SelectedItem != null)
{
switch (lvQueries.SelectedItem.Text)
{
case ("Vertex/Node"):
_controller.SelectBy = vtkSelectBy.QueryNode;
_controller.Selection.SelectItem = vtkSelectItem.Node;
_numOfNodesToSelect = 1;
break;
case ("Facet/Element"):
_controller.SelectBy = vtkSelectBy.QueryElement;
_controller.Selection.SelectItem = vtkSelectItem.Element;
_numOfNodesToSelect = -1;
break;
case ("Edge"):
_controller.SelectBy = vtkSelectBy.QueryEdge;
_controller.Selection.SelectItem = vtkSelectItem.GeometryEdge;
_numOfNodesToSelect = -1;
break;
case ("Surface"):
_controller.SelectBy = vtkSelectBy.QuerySurface;
_controller.Selection.SelectItem = vtkSelectItem.Surface;
_numOfNodesToSelect = -1;
break;
case ("Part"):
_controller.SelectBy = vtkSelectBy.QueryPart;
_controller.Selection.SelectItem = vtkSelectItem.Part;
_numOfNodesToSelect = -1;
break;
case ("Assembly"):
_controller.SelectBy = vtkSelectBy.Default;
_controller.Selection.SelectItem = vtkSelectItem.None;
OutputAssemblyData();
_numOfNodesToSelect = -1;
break;
case ("Bounding box size"):
_controller.SelectBy = vtkSelectBy.Default;
_controller.Selection.SelectItem = vtkSelectItem.None;
OutputBoundingBox();
_numOfNodesToSelect = -1;
break;
case ("Distance"):
_controller.SelectBy = vtkSelectBy.QueryNode;
_controller.Selection.SelectItem = vtkSelectItem.Node;
_numOfNodesToSelect = 2;
break;
case ("Angle"):
_controller.SelectBy = vtkSelectBy.QueryNode;
_controller.Selection.SelectItem = vtkSelectItem.Node;
_numOfNodesToSelect = 3;
break;
case ("Circle"):
_controller.SelectBy = vtkSelectBy.QueryNode;
_controller.Selection.SelectItem = vtkSelectItem.Node;
_numOfNodesToSelect = 3;
break;
default:
break;
}
// Clear
RemoveMeasureAnnotation();
_controller.ClearSelectionHistoryAndCallSelectionChanged();
}
}
catch { }
}
private void btnClear_Click(object sender, EventArgs e)
{
// Annotations
Form_RemoveAnnotations?.Invoke(null, null);
// Selection
_controller.ClearSelectionHistoryAndCallSelectionChanged();
}
private void btnClose_Click(object sender, EventArgs e)
{
Hide();
}
private void FrmQuery_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
Hide();
}
}
private void FrmQuery_VisibleChanged(object sender, EventArgs e)
{
// This is called if some other form is shown to close all other forms
// This is called after the form visibility changes
if (this.Visible)
{
if (lvQueries.SelectedItem == null) lvQueries.Items[0].Selected = true;
if (lvQueries.SelectedItem != null) lvQueries.SelectedItem.Selected = true;
lvQueries.Focus();
}
// The form was hidden
else
{
_controller.SelectBy = vtkSelectBy.Default;
// Clear
RemoveMeasureAnnotation();
_controller.ClearSelectionHistoryAndCallSelectionChanged();
}
}
// Methods
public void PrepareForm(Controller controller)
{
_controller = controller;
lvQueries.HideSelection = false;
lvQueries.SelectedIndices.Clear();
//
_controller.SetSelectByToOff();
}
//
public void PickedIds(int[] ids)
{
try
{
// Clear annotations
RemoveMeasureAnnotation();
//
if (ids == null || ids.Length == 0) return;
//
if (_controller.SelectBy == vtkSelectBy.QueryElement && ids.Length == 1) OneElementPicked(ids[0]);
else if (_controller.SelectBy == vtkSelectBy.QueryEdge && ids.Length == 1) OneEdgePicked(ids[0]);
else if (_controller.SelectBy == vtkSelectBy.QuerySurface)
{
SelectionNodeMouse selectionNodeMouse = _controller.Selection.Nodes[0] as SelectionNodeMouse;
if (selectionNodeMouse != null)
{
// Clear - to remove this mouseSelectionNode from the history which is used for speed optimization
_controller.Selection.Clear();
ids = _controller.GetIdsFromSelectionNodeMouse(selectionNodeMouse, true);
OneSurfacePicked(ids[0]);
}
}
else if (_controller.SelectBy == vtkSelectBy.QueryPart && ids.Length == 1) OnePartPicked(ids[0]);
else if (ids.Length == _numOfNodesToSelect)
{
// One node
if (ids.Length == 1) OneNodePicked(ids[0]);
// Two nodes
else if (ids.Length == 2) TwoNodesPicked(ids[0], ids[1]);
// Three nodes
else if (ids.Length == 3) ThreeNodesPicked(ids[0], ids[1], ids[2]);
//
_controller.ClearSelectionHistoryAndCallSelectionChanged();
//
HighlightNodes();
}
}
catch
{ }
}
//
public void OneNodePicked(int nodeId)
{
if (Form_WriteDataToOutput != null)
{
string data;
string lenUnit = _controller.GetLengthUnit();
string lenUnitInBrackets = string.Format("[{0}]", lenUnit);
_coorNodesToDraw = new double[_numOfNodesToSelect][];
//
Vec3D baseV = new Vec3D(_controller.GetNode(nodeId).Coor);
// Item name
string itemName = "Node";
if (_controller.CurrentView == ViewGeometryModelResults.Geometry) itemName = "Vertex";
//
Form_WriteDataToOutput("");
data = string.Format("{0,16}{1,8}{2,16}{3,16}", itemName.PadRight(16), "[/]", "id:", nodeId);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}",
"Base".PadRight(16), lenUnitInBrackets, "x, y, z:", baseV.X, baseV.Y, baseV.Z);
Form_WriteDataToOutput(data);
//
if (_controller.CurrentView == ViewGeometryModelResults.Results)
{
float fieldValue = _controller.GetNodalValue(nodeId);
string fieldUnit = "[" + _controller.GetCurrentResultsUnitAbbreviation() + "]";
//
Vec3D trueScaledV = new Vec3D(_controller.GetScaledNode(1, nodeId).Coor);
Vec3D disp = trueScaledV - baseV;
//
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}",
"Deformed".PadRight(16), lenUnitInBrackets, "x, y, z:",
trueScaledV.X, trueScaledV.Y, trueScaledV.Z);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}",
"Displacement".PadRight(16), lenUnitInBrackets, "x, y, z:", disp.X, disp.Y, disp.Z);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}", "Field value".PadRight(16), fieldUnit, ":", fieldValue);
Form_WriteDataToOutput(data);
//
float scale = _controller.GetScale();
baseV = new Vec3D(_controller.GetScaledNode(scale, nodeId).Coor); // for the _coorNodesToDraw
}
//
Form_WriteDataToOutput("");
//
_coorNodesToDraw[0] = baseV.Coor;
_coorLinesToDraw = null;
//
_controller.Annotations.AddNodeAnnotation(nodeId);
}
}
public void OneElementPicked(int elementId)
{
// Item name
string itemName = "Element id:";
if (_controller.CurrentView == ViewGeometryModelResults.Geometry) itemName = "Facet id:";
//
Form_WriteDataToOutput("");
string data = string.Format("{0,16}{1,8}", itemName.PadRight(16), elementId);
Form_WriteDataToOutput(data);
if (_controller.CurrentView == ViewGeometryModelResults.Model)
{
string elementType = _controller.GetElementType(elementId);
data = string.Format("{0,16}{1,8}", "Element type:".PadRight(16), elementType);
Form_WriteDataToOutput(data);
}
//
Form_WriteDataToOutput("");
//
_controller.ClearSelectionHistoryAndCallSelectionChanged();
//
_controller.HighlightElement(elementId);
//
_controller.Annotations.AddElementAnnotation(elementId);
}
public void OneEdgePicked(int geometryId)
{
int[] itemTypePartIds = FeMesh.GetItemTypePartIdsFromGeometryId(geometryId);
BasePart part = _controller.DisplayedMesh.GetPartFromId(itemTypePartIds[2]);
int edgeId = itemTypePartIds[0];
double length1 = _controller.DisplayedMesh.GetEdgeLength(geometryId);
string lenUnit = _controller.GetLengthUnit();
string lenUnitInBrackets = string.Format("[{0}]", lenUnit);
//
Form_WriteDataToOutput("");
string data = string.Format("Edge on part: {0}", part.Name);
if (part.Visualization.EdgeTypes != null)
{
data += string.Format(" Edge type: {0}", part.Visualization.EdgeTypes[edgeId]);
}
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16}", "Edge".PadRight(16), "[/]", "id:", edgeId + 1);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}", "Base".PadRight(16), lenUnitInBrackets, "L:", length1);
Form_WriteDataToOutput(data);
//
if (_controller.CurrentView == ViewGeometryModelResults.Results)
{
int[] nodeIds;
_controller.DisplayedMesh.GetEdgeNodeCoor(geometryId, out nodeIds, out double[][] nodeCoor);
FeNode[] nodes = _controller.GetScaledNodes(1, nodeIds);
double length2 = 0;
Vec3D n1;
Vec3D n2;
for (int i = 0; i < nodes.Length - 1; i++)
{
n1 = new Vec3D(nodes[i].Coor);
n2 = new Vec3D(nodes[i + 1].Coor);
length2 += (n2 - n1).Len;
}
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}", "Deformed".PadRight(16), lenUnitInBrackets, "L:", length2);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}", "Delta".PadRight(16), lenUnitInBrackets, "L:", length2 - length1);
Form_WriteDataToOutput(data);
}
Form_WriteDataToOutput("");
//
_controller.ClearSelectionHistoryAndCallSelectionChanged();
//
_controller.HighlightItemsByGeometryEdgeIds(new int[] { geometryId }, false);
//
_controller.Annotations.AddEdgeAnnotation(geometryId);
}
public void OneSurfacePicked(int geometryId)
{
int[] itemTypePartIds = FeMesh.GetItemTypePartIdsFromGeometryId(geometryId);
BasePart part = _controller.DisplayedMesh.GetPartFromId(itemTypePartIds[2]);
int surfaceId = itemTypePartIds[0];
int numEdges = part.Visualization.FaceEdgeIds[surfaceId].Length;
int numVertices = part.Visualization.GetVertexNodeIdsForSurfaceId(surfaceId).Length;
double area1 = _controller.DisplayedMesh.GetSurfaceArea(geometryId);
string areaUnit = "[" + _controller.GetAreaUnit() + "]";
//
Form_WriteDataToOutput("");
string data = string.Format("Surface on part: {0}", part.Name);
if (part.Visualization.FaceTypes != null)
{
data += string.Format(" Surface type: {0}", part.Visualization.FaceTypes[surfaceId]);
}
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16}", "Surface".PadRight(16), "[/]", "id:", surfaceId + 1);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16}", "Edges".PadRight(16), "[/]", "#:", numEdges);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16}", "Vertices".PadRight(16), "[/]", "#:", numVertices);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}", "Base".PadRight(16), areaUnit, "A:", area1);
Form_WriteDataToOutput(data);
//
if (_controller.CurrentView == ViewGeometryModelResults.Results)
{
int[] nodeIds;
_controller.DisplayedMesh.GetFaceNodes(geometryId, out nodeIds);
FeNode[] nodes = _controller.GetScaledNodes(1, nodeIds);
Dictionary<int, FeNode> nodesDic = new Dictionary<int, FeNode>();
for (int i = 0; i < nodes.Length; i++) nodesDic.Add(nodes[i].Id, nodes[i]);
double area2 = _controller.DisplayedMesh.ComputeFaceArea(part.Visualization, surfaceId, nodesDic);
//
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}", "Deformed".PadRight(16), areaUnit, "A:", area2);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}", "Delta".PadRight(16), areaUnit, "A:", area2 - area1);
Form_WriteDataToOutput(data);
}
Form_WriteDataToOutput("");
//
_controller.ClearSelectionHistoryAndCallSelectionChanged(); // in order to prevent SHIFT ADD
//
_controller.HighlightItemsBySurfaceIds(new int[] { geometryId }, false);
//
_controller.Annotations.AddSurfaceAnnotation(geometryId);
}
public void OnePartPicked(int partId)
{
FeMesh mesh = _controller.DisplayedMesh;
//
BasePart part = mesh.GetPartFromId(partId);
if (part == null) throw new NotSupportedException();
//
Form_WriteDataToOutput("");
string data = string.Format("Part name: {0}", part.Name);
Form_WriteDataToOutput(data);
data = string.Format("Part id: {0}", part.PartId);
Form_WriteDataToOutput(data);
data = string.Format("Part type: {0}", part.PartType);
Form_WriteDataToOutput(data);
// Item name
string elementsName = "Number of elements:";
string nodesName = "Number of nodes:";
if (_controller.CurrentView == ViewGeometryModelResults.Geometry)
{
elementsName = "Number of facets:";
nodesName = "Number of vertices:";
}
data = string.Format("{0} {1}", elementsName, part.Labels.Length);
Form_WriteDataToOutput(data);
data = string.Format("{0} {1}", nodesName, part.NodeLabels.Length);
Form_WriteDataToOutput(data);
//
string volumeArea = "Area:";
string unit = _controller.GetAreaUnit();
bool volume = part.PartType == PartType.SolidAsShell || part.PartType == PartType.Solid ||
part.PartType == PartType.Compound;
if (part is ResultPart)
{
if (volume)
{
volumeArea = "Undeformed volume:";
unit = _controller.GetVolumeUnit();
}
else
{
volumeArea = "Undeformed area:";
unit = _controller.GetAreaUnit();
}
}
else
{
if (volume)
{
volumeArea = "Volume:";
unit = _controller.GetVolumeUnit();
}
else
{
volumeArea = "Area:";
unit = _controller.GetAreaUnit();
}
}
//
data = string.Format("{0} {1,16:E} {2}", volumeArea, part.MassProperties.Volume, unit);
Form_WriteDataToOutput(data);
//
Form_WriteDataToOutput("");
//
_controller.ClearSelectionHistoryAndCallSelectionChanged();
//
_controller.Highlight3DObjects(new object[] { part });
//
_controller.Annotations.AddPartAnnotation(part.Name);
}
private void OutputAssemblyData()
{
FeMesh mesh = _controller.DisplayedMesh;
if (mesh == null) return;
double[] bb = _controller.GetBoundingBox();
double[] size = new double[] { bb[1] - bb[0], bb[3] - bb[2], bb[5] - bb[4] };
//
Form_WriteDataToOutput("");
string data = string.Format("Assembly");
Form_WriteDataToOutput(data);
data = string.Format("Number of parts: {0}", mesh.Parts.Count);
Form_WriteDataToOutput(data);
// Item name
string elementsName = "Number of elements:";
string nodesName = "Number of nodes:";
if (_controller.CurrentView == ViewGeometryModelResults.Geometry)
{
elementsName = "Number of facets:";
nodesName = "Number of vertices:";
}
data = string.Format("{0} {1}", elementsName, mesh.Elements.Count);
Form_WriteDataToOutput(data);
data = string.Format("{0} {1}", nodesName, mesh.Nodes.Count);
Form_WriteDataToOutput(data);
Form_WriteDataToOutput("");
}
private void OutputBoundingBox()
{
double[] bb = _controller.GetBoundingBox();
double[] size = new double[] { bb[1] - bb[0], bb[3] - bb[2], bb[5] - bb[4] };
string lenUnit = _controller.GetLengthUnit();
string lenUnitInBrackets = string.Format("[{0}]", lenUnit);
//
Form_WriteDataToOutput("");
string data = string.Format("Bounding box");
Form_WriteDataToOutput(data);
if (_controller.CurrentView == ViewGeometryModelResults.Results)
{
double scale = _controller.GetScale();
data = string.Format("{0,17}{1,7}{2,16}{3,16:E}", "Def. scale factor".PadRight(17), "[/]", "sf:", scale);
Form_WriteDataToOutput(data);
}
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}", "Min".PadRight(16), lenUnitInBrackets,
"x, y, z:", bb[0], bb[2], bb[4]);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}", "Max".PadRight(16), lenUnitInBrackets,
"x, y, z:", bb[1], bb[3], bb[5]);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}", "Size".PadRight(16), lenUnitInBrackets,
"x, y, z:", size[0], size[1], size[2]);
Form_WriteDataToOutput(data);
}
public void TwoNodesPicked(int nodeId1, int nodeId2)
{
if (Form_WriteDataToOutput != null)
{
string data;
_coorNodesToDraw = new double[_numOfNodesToSelect][];
//
Vec3D trueScaledD = null;
Vec3D baseV1 = new Vec3D(_controller.GetNode(nodeId1).Coor);
Vec3D baseV2 = new Vec3D(_controller.GetNode(nodeId2).Coor);
Vec3D baseD = baseV2 - baseV1;
string lenUnit = _controller.GetLengthUnit();
string lenUnitInBrackets = string.Format("[{0}]", lenUnit);
//
Form_WriteDataToOutput("");
data = string.Format(
"{0,16}{1,8}{2,16}{3,16}, {4,16}", "Distance".PadRight(16), "[/]", "id1, id2:", nodeId1, nodeId2);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}, {6,16:E}",
"Base".PadRight(16), lenUnitInBrackets, "dx, dy, dz, D:", baseD.X, baseD.Y, baseD.Z, baseD.Len);
Form_WriteDataToOutput(data);
//
if (_controller.CurrentView == ViewGeometryModelResults.Results)
{
Vec3D trueScaledV1 = new Vec3D(_controller.GetScaledNode(1, nodeId1).Coor);
Vec3D trueScaledV2 = new Vec3D(_controller.GetScaledNode(1, nodeId2).Coor);
trueScaledD = trueScaledV2 - trueScaledV1;
Vec3D delta = trueScaledD - baseD;
//
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}, {6,16:E}",
"Deformed".PadRight(16), lenUnitInBrackets, "dx, dy, dz, D:",
trueScaledD.X, trueScaledD.Y, trueScaledD.Z, trueScaledD.Len);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}, {6,16:E}",
"Delta".PadRight(16), lenUnitInBrackets, "dx, dy, dz, D:",
delta.X, delta.Y, delta.Z, trueScaledD.Len - baseD.Len);
Form_WriteDataToOutput(data);
//
float scale = _controller.GetScale();
baseV1 = new Vec3D(_controller.GetScaledNode(scale, nodeId1).Coor); // for the _coorNodesToDraw
baseV2 = new Vec3D(_controller.GetScaledNode(scale, nodeId2).Coor); // for the _coorNodesToDraw
}
Form_WriteDataToOutput("");
//
_coorNodesToDraw[0] = baseV1.Coor;
_coorNodesToDraw[1] = baseV2.Coor;
_coorLinesToDraw = _coorNodesToDraw;
// Annotation
string text;
string numberFormat = _controller.Settings.Annotations.GetNumberFormat();
//
if (trueScaledD != null) baseD = trueScaledD;
//
text = string.Format("Distance: {0} {1}{2}", baseD.Len.ToString(numberFormat), lenUnit, Environment.NewLine);
text += string.Format("dx: {0} {1}{2}", baseD.X.ToString(numberFormat), lenUnit, Environment.NewLine);
text += string.Format("dy: {0} {1}{2}", baseD.Y.ToString(numberFormat), lenUnit, Environment.NewLine);
text += string.Format("dz: {0} {1}", baseD.Z.ToString(numberFormat), lenUnit);
//
Vec3D anchor = (baseV1 + baseV2) * 0.5;
_controller.Annotations.AddMeasureAnnotation(text, anchor.Coor);
}
}
public void ThreeNodesPicked(int nodeId1, int nodeId2, int nodeId3)
{
if (Form_WriteDataToOutput != null)
{
if (lvQueries.SelectedItem.Text == "Angle") ComputeAngle(nodeId1, nodeId2, nodeId3);
else if (lvQueries.SelectedItem.Text == "Circle") ComputeCircle(nodeId1, nodeId2, nodeId3);
}
}
//
private void ComputeAngle(int nodeId1, int nodeId2, int nodeId3)
{
System.Diagnostics.Debug.Write(nodeId1 + " " + nodeId2 + " " + nodeId3);
string data;
double angle;
double angle2draw;
Vec3D p;
Vec3D axis;
Vec3D baseV1 = new Vec3D(_controller.GetNode(nodeId1).Coor);
Vec3D baseV2 = new Vec3D(_controller.GetNode(nodeId2).Coor);
Vec3D baseV3 = new Vec3D(_controller.GetNode(nodeId3).Coor);
//
angle = ComputeAngle(baseV1, baseV2, baseV3, out p, out axis);
angle2draw = angle;
string angleUnit = StringAngleDegConverter.GetUnitAbbreviation();
string angleUnitInBrackets = "[" + angleUnit + "]";
//
data = string.Format("{0,16}{1,8}{2,16}{3,16}, {4,16}, {5,16}",
"Angle".PadRight(16), "[/]", "id1, id2, id3:", nodeId1, nodeId2, nodeId3);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}", "Base".PadRight(16), angleUnitInBrackets, "ϕ:", angle);
Form_WriteDataToOutput(data);
//
if (_controller.CurrentView == ViewGeometryModelResults.Results)
{
baseV1 = new Vec3D(_controller.GetScaledNode(1, nodeId1).Coor);
baseV2 = new Vec3D(_controller.GetScaledNode(1, nodeId2).Coor);
baseV3 = new Vec3D(_controller.GetScaledNode(1, nodeId3).Coor);
//
double angle2 = ComputeAngle(baseV1, baseV2, baseV3, out p, out axis);
double delta = angle2 - angle;
//
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}", "Deformed".PadRight(16), angleUnitInBrackets, "ϕ:", angle2);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}", "Delta".PadRight(16), angleUnitInBrackets, "ϕ:", delta);
Form_WriteDataToOutput(data);
//
float scale = _controller.GetScale();
baseV1 = new Vec3D(_controller.GetScaledNode(scale, nodeId1).Coor); // for the _coorNodesToDraw
baseV2 = new Vec3D(_controller.GetScaledNode(scale, nodeId2).Coor); // for the _coorNodesToDraw
baseV3 = new Vec3D(_controller.GetScaledNode(scale, nodeId3).Coor); // for the _coorNodesToDraw
//
angle = angle2; // for the annotation
angle2draw = ComputeAngle(baseV1, baseV2, baseV3, out p, out axis); // for drawing
}
Form_WriteDataToOutput("");
//
_coorNodesToDraw = new double[_numOfNodesToSelect][];
_coorNodesToDraw[0] = baseV1.Coor;
_coorNodesToDraw[1] = baseV2.Coor;
_coorNodesToDraw[2] = baseV3.Coor;
//
List<double[]> coorLines = new List<double[]>() { baseV1.Coor, baseV2.Coor, baseV3.Coor, baseV2.Coor };
coorLines.AddRange(ComputeCirclePoints(baseV2, axis, p, angle2draw * Math.PI / 180));
_coorLinesToDraw = coorLines.ToArray();
// Annotation
string text;
string numberFormat = _controller.Settings.Annotations.GetNumberFormat();
//
text = string.Format("Angle: {0}{1}", angle.ToString(numberFormat), angleUnit);
//
double[] anchor = _coorLinesToDraw[_coorLinesToDraw.Length / 2];
_controller.Annotations.AddMeasureAnnotation(text, anchor);
}
private void ComputeCircle(int nodeId1, int nodeId2, int nodeId3)
{
// https://en.wikipedia.org/wiki/Circumscribed_circle
string data;
double r;
Vec3D center;
Vec3D axis;
double rDraw;
Vec3D centerDraw;
Vec3D axisDraw;
Vec3D baseV1 = new Vec3D(_controller.GetNode(nodeId1).Coor);
Vec3D baseV2 = new Vec3D(_controller.GetNode(nodeId2).Coor);
Vec3D baseV3 = new Vec3D(_controller.GetNode(nodeId3).Coor);
//
double arcAngleDeg;
Vec3D.GetCircle(baseV1, baseV2, baseV3, out r, out arcAngleDeg, out center, out axis);
rDraw = r;
centerDraw = center;
axisDraw = axis;
string lenUnit = _controller.GetLengthUnit();
string lenUnitInBrackets = string.Format("[{0}]", lenUnit);
//
Form_WriteDataToOutput("");
data = string.Format("{0,16}{1,8}{2,16}{3,16}, {4,16}, {5,16}",
"Circle".PadRight(16), "[/]", "id1, id2, id3:", nodeId1, nodeId2, nodeId3);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}, {6,16:E}",
"Base".PadRight(16), lenUnitInBrackets, "x, y, z, R:", center.X, center.Y, center.Z, r);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}",
"Base axis".PadRight(16), lenUnitInBrackets, "x, y, z:", axis.X, axis.Y, axis.Z);
Form_WriteDataToOutput(data);
//
if (_controller.CurrentView == ViewGeometryModelResults.Results)
{
baseV1 = new Vec3D(_controller.GetScaledNode(1, nodeId1).Coor);
baseV2 = new Vec3D(_controller.GetScaledNode(1, nodeId2).Coor);
baseV3 = new Vec3D(_controller.GetScaledNode(1, nodeId3).Coor);
//
Vec3D.GetCircle(baseV1, baseV2, baseV3, out r, out center, out axis);
//
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}, {6,16:E}",
"Deformed".PadRight(16), lenUnitInBrackets, "x, y, z, R:", center.X, center.Y, center.Z, r);
Form_WriteDataToOutput(data);
data = string.Format("{0,16}{1,8}{2,16}{3,16:E}, {4,16:E}, {5,16:E}",
"Deformed axis".PadRight(16), lenUnitInBrackets, "x, y, z:", axis.X, axis.Y, axis.Z);
Form_WriteDataToOutput(data);
//
float scale = _controller.GetScale();
baseV1 = new Vec3D(_controller.GetScaledNode(scale, nodeId1).Coor); // for the _coorNodesToDraw
baseV2 = new Vec3D(_controller.GetScaledNode(scale, nodeId2).Coor); // for the _coorNodesToDraw
baseV3 = new Vec3D(_controller.GetScaledNode(scale, nodeId3).Coor); // for the _coorNodesToDraw
//
Vec3D.GetCircle(baseV1, baseV2, baseV3, out rDraw, out centerDraw, out axisDraw);
}
Form_WriteDataToOutput("");
//
_coorNodesToDraw = new double[_numOfNodesToSelect + 1][];
_coorNodesToDraw[0] = baseV1.Coor;
_coorNodesToDraw[1] = baseV2.Coor;
_coorNodesToDraw[2] = baseV3.Coor;
_coorNodesToDraw[3] = centerDraw.Coor;
//
_coorLinesToDraw = ComputeCirclePoints(centerDraw, axisDraw, baseV1, 2 * Math.PI);
// Annotation
string text;
string numberFormat = _controller.Settings.Annotations.GetNumberFormat();
//
text = string.Format("Radius: {0} {1}{2}", r.ToString(numberFormat), lenUnit, Environment.NewLine);
text += string.Format("X: {0} {1}{2}", center.X.ToString(numberFormat), lenUnit, Environment.NewLine);
text += string.Format("Y: {0} {1}{2}", center.Y.ToString(numberFormat), lenUnit, Environment.NewLine);
text += string.Format("Z: {0} {1}", center.Z.ToString(numberFormat), lenUnit);
//
double[] anchor = _coorLinesToDraw[2];
_controller.Annotations.AddMeasureAnnotation(text, anchor);
}
private double ComputeAngle(Vec3D baseV1, Vec3D baseV2, Vec3D baseV3, out Vec3D p, out Vec3D axis)
{
Vec3D line1 = baseV1 - baseV2;
Vec3D line2 = baseV3 - baseV2;
//
if (line1.Len2 > line2.Len2) // find shorter line
{
p = baseV2 + line2 * 0.5;
axis = Vec3D.CrossProduct(line2, line1);
}
else
{
p = baseV2 + line1 * 0.5;
axis = Vec3D.CrossProduct(line1, line2);
}
axis.Normalize();
line1.Normalize();
line2.Normalize();
//
double angle = Math.Acos(Vec3D.DotProduct(line1, line2)) * 180 / Math.PI;
return angle;
}
private double[][] ComputeCirclePoints(Vec3D c, Vec3D axis, Vec3D p, double angle)
{
// The circe is constructed by moving the r vector around the axis
// d vector is the change in normal n and perpendicular r direction
int segments = 40;
double [][] coorLines = new double[segments + 1][];
double dAngle = angle / segments;
Vec3D r = p - c;
double rLen = r.Len;
Vec3D n;
Vec3D d;
//
coorLines[0] = p.Coor;
for (int i = 0; i < segments; i++)
{
n = Vec3D.CrossProduct(axis, r);
n.Normalize();
//
d = rLen * Math.Sin(dAngle) * n - (1 - Math.Cos(dAngle)) * r;
p = p + d;
r = r + d;
//
coorLines[i + 1] = p.Coor;
}
return coorLines;
}
//
private void RemoveMeasureAnnotation()
{
_controller.Annotations.RemoveCurrentMeasureAnnotation();
}
private void HighlightNodes()
{
if (_coorNodesToDraw != null)
{
if (_coorNodesToDraw.GetLength(0) == 1)
{
_controller.HighlightNodes(_coorNodesToDraw);
}
else if (_coorNodesToDraw.GetLength(0) >= 2)
{
_controller.HighlightNodes(_coorNodesToDraw);
_controller.HighlightConnectedLines(_coorLinesToDraw);
}
}
}
}
}