using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Kitware.VTK; using CaeGlobals; using static System.Windows.Forms.LinkLabel; using System.Security.Policy; using System.Threading; namespace vtkControl { public class vtkMaxActor { // Variables protected string _name; protected vtkMaxExtreemeNode _minNode; protected vtkMaxExtreemeNode _maxNode; // protected vtkMapper _geometryMapper; protected vtkActor _geometry; protected vtkActor _elementEdges; protected vtkActor _modelEdges; protected vtkActor _nodes; // protected vtkProperty _geometryProperty; protected vtkProperty _elementEdgesProperty; protected vtkProperty _modelEdgesProperty; protected vtkProperty _nodesProperty; // protected vtkPointData _geometryPointData; protected vtkCellLocator _cellLocator; // for surface picking protected vtkCellLocator _frustumCellLocator; // for volume picking protected vtkPointData _frustumPointData; protected vtkMaxActor _sectionViewActor; protected List _copies; // protected bool _isAPart; protected vtkMaxActorRepresentation _actorRepresentation; // protected bool _visible; protected bool _backfaceCulling; protected System.Drawing.Color _color; protected System.Drawing.Color _backfaceColor; protected System.Drawing.Color[] _colorTable; protected double _ambient; protected double _diffuse; protected bool _colorContours; protected bool _sectionViewPossible; protected bool _drawOnGeometry; protected bool _useSecondaryHighlightColor; // protected bool _canHaveElementEdges; protected vtkRendererLayer _layer; // Properties public string Name { get { return _name; } set { _name = value; } } public vtkMaxExtreemeNode MinNode { get { return _minNode; } set { _minNode = value; } } public vtkMaxExtreemeNode MaxNode { get { return _maxNode; } set { _maxNode = value; } } // public vtkMapper GeometryMapper { get { return _geometryMapper; } set { _geometryMapper = value; if (_geometry != null) _geometry.SetMapper(_geometryMapper); } } // Actors public vtkActor Geometry { get { return _geometry; } set { _geometry = value; if (_geometry != null) { _geometryMapper = _geometry.GetMapper(); _geometryProperty = _geometry.GetProperty(); } } } public vtkActor ElementEdges { get { return _elementEdges; } set { _elementEdges = value; if (_elementEdges != null) _elementEdgesProperty = _elementEdges.GetProperty(); } } public vtkActor ModelEdges { get { return _modelEdges; } set { _modelEdges = value; if (_modelEdges != null) _modelEdgesProperty = _modelEdges.GetProperty(); } } public vtkActor Nodes { get { return _nodes; } set { _nodes = value; if (_nodes != null) _nodesProperty = _nodes.GetProperty(); } } // Properties public vtkProperty GeometryProperty { get { return _geometryProperty; } set { _geometryProperty = value; if (_geometry != null) _geometry.SetProperty(_geometryProperty); } } public vtkProperty ElementEdgesProperty { get { return _elementEdgesProperty; } set { _elementEdgesProperty = value; } } public vtkProperty ModelEdgesProperty { get { return _modelEdgesProperty; } set { _modelEdgesProperty = value; } } // public vtkPointData GeometryPointData { get { return _geometryPointData; } } public vtkCellLocator CellLocator { get { return _cellLocator; } set { _cellLocator = value; } } public vtkCellLocator FrustumCellLocator { get { return _frustumCellLocator; } set { _frustumCellLocator = value; } } public vtkPointData FrustumPointData { get { return _frustumPointData; } } public vtkMaxActor SectionViewActor { get { return _sectionViewActor; } set { _sectionViewActor = value; } } public List Copies { get { return _copies; } } // public int GetNumberOfElements() { return _geometryMapper != null ? (int)_geometryMapper.GetInput().GetNumberOfCells() : 0; } public bool IsAPart { get { return _isAPart; } } public vtkMaxActorRepresentation ActorRepresentation { get { return _actorRepresentation; } set { _actorRepresentation = value; } } public virtual bool VtkMaxActorVisible { get { return _visible; } set { _visible = value; if (_geometry != null) _geometry.SetVisibility(_visible ? 1 : 0); // to base vtkActor } } public bool BackfaceCulling { get { return _backfaceCulling; } set { _backfaceCulling = value; } } public bool Pickable { get { return _geometry.GetPickable() == 1; } } public System.Drawing.Color Color { get { return _color; } set { _color = value; UpdateColor(); } } public System.Drawing.Color BackfaceColor { get { return _backfaceColor; } set { _backfaceColor = value; UpdateColor(); } } public System.Drawing.Color[] ColorTable { get { return _colorTable; } set { _colorTable = value; UpdateColor(); } } public double Ambient { get { return _ambient; } set { _ambient = value; UpdateColor(); } } public double Diffuse { get { return _diffuse; } set { _diffuse = value; UpdateColor(); } } public bool ColorContours { get { return _colorContours; } set { _colorContours = value; } } public bool SectionViewPossible { get { return _sectionViewPossible; } set { _sectionViewPossible = value; } } public bool DrawOnGeometry { get { return _drawOnGeometry; } set { _drawOnGeometry = value; } } public bool UseSecondaryHighlightColor { get { return _useSecondaryHighlightColor; } set { _useSecondaryHighlightColor = value; } } public bool CanHaveElementEdges { get { return _canHaveElementEdges; } set { _canHaveElementEdges = value; } } public vtkRendererLayer Layer { get { return _layer; } set { _layer = value; } } // Constructors public vtkMaxActor() { _name = null; _minNode = null; _maxNode = null; // _geometry = new vtkActor(); _elementEdges = null; _modelEdges = null; // _geometryProperty = _geometry.GetProperty(); _elementEdgesProperty = null; _modelEdgesProperty = null; // _geometryMapper = _geometry.GetMapper(); // _cellLocator = null; _frustumCellLocator = null; _sectionViewActor = null; _copies = new List(); // _isAPart = false; _actorRepresentation = vtkMaxActorRepresentation.Unknown; _visible = true; _backfaceCulling = true; _color = System.Drawing.Color.Empty; _backfaceColor = System.Drawing.Color.Empty; _colorTable = null; _ambient = 0.5; _diffuse = 0.5; _colorContours = false; _sectionViewPossible = true; _drawOnGeometry = false; _useSecondaryHighlightColor = false; // _canHaveElementEdges = false; _layer = vtkRendererLayer.Base; // UpdateColor(); } public vtkMaxActor(vtkUnstructuredGrid source) : this () { // Unstructured grid vtkUnstructuredGrid uGridActor = vtkUnstructuredGrid.New(); vtkUnstructuredGrid uGridEdges = vtkUnstructuredGrid.New(); // Add the points uGridActor.SetPoints(source.GetPoints()); uGridEdges.SetPoints(source.GetPoints()); // Add the cells AddCellDataToGrid(source, uGridActor, uGridEdges); // Update grid uGridActor.Update(); uGridEdges.Update(); // Actor vtkDataSetMapper mapper = vtkDataSetMapper.New(); mapper.SetInput(uGridActor); _geometryMapper = mapper; _geometry.SetMapper(_geometryMapper); _geometry.PickableOff(); _geometryProperty = _geometry.GetProperty(); // Edges _elementEdges = GetActorEdgesFromGridByVisualizationSurfaceExtraction(uGridEdges); if (_elementEdges != null) _elementEdgesProperty = _elementEdges.GetProperty(); } public vtkMaxActor(vtkMaxActorData data) : this(data, false, false) { } public vtkMaxActor(vtkMaxActorData data, vtkMapper mapper) : this() { _name = data.Name; _geometryMapper = mapper; _geometry.SetMapper(_geometryMapper); _geometry.SetPickable(data.Pickable ? 1 : 0); _geometry.GetProperty().SetLineWidth(data.LineWidth); // _geometryProperty = _geometry.GetProperty(); // _actorRepresentation = data.ActorRepresentation; _backfaceCulling = data.BackfaceCulling; _color = data.Color; _backfaceColor = data.BackfaceColor; _colorTable = data.ColorTable; _ambient = data.Ambient; _diffuse = data.Diffuse; _colorContours = data.ColorContours; _sectionViewPossible = data.SectionViewPossible; _drawOnGeometry = data.DrawOnGeometry; _useSecondaryHighlightColor = data.UseSecondaryHighlightColor; // _canHaveElementEdges = data.CanHaveElementEdges; _layer = data.Layer; // UpdateColor(); } public vtkMaxActor(vtkMaxActorData data, bool extractVisualizationSurface, bool createNodalActor) : this() { _name = data.Name; // if ((data.Geometry.Cells.CellNodeIds == null && data.Geometry.Nodes.Coor != null) || createNodalActor) { CreateNodalActor(data); } else { if (extractVisualizationSurface) CreateFromDataByVisualizationSurfaceExtraction(data); else { CreatePolyFromData(data); } // if (data.Pickable && _geometryMapper.GetInputAsDataSet().GetCellData().GetGlobalIds() != null) { _geometry.SetPickable(1); _cellLocator = vtkCellLocator.New(); _cellLocator.SetDataSet(_geometryMapper.GetInputAsDataSet()); _cellLocator.LazyEvaluationOn(); } else { _geometry.SetPickable(0); } } // Property _geometryProperty.SetLineWidth(data.LineWidth); _geometryProperty.SetPointSize(data.NodeSize); if (_modelEdgesProperty != null) _modelEdgesProperty.SetPointSize(data.NodeSize); if (_elementEdgesProperty != null) _elementEdgesProperty.SetPointSize(data.NodeSize); // _isAPart = data.IsAPart; _actorRepresentation = data.ActorRepresentation; _backfaceCulling = data.BackfaceCulling; _color = data.Color; _backfaceColor = data.BackfaceColor; _colorTable = data.ColorTable; _ambient = data.Ambient; _diffuse = data.Diffuse; _colorContours = data.ColorContours; _sectionViewPossible = data.SectionViewPossible; _drawOnGeometry = data.DrawOnGeometry; _useSecondaryHighlightColor = data.UseSecondaryHighlightColor; // _canHaveElementEdges = data.CanHaveElementEdges; _layer = data.Layer; // UpdateColor(); } public vtkMaxActor(vtkMaxActor sourceActor) : this() { _name = sourceActor.Name; // if (sourceActor.MinNode != null) _minNode = new vtkMaxExtreemeNode(sourceActor.MinNode); if (sourceActor.MaxNode != null) _maxNode = new vtkMaxExtreemeNode(sourceActor.MaxNode); // // Geometry // Poly data vtkPolyData polyData = vtkPolyData.New(); polyData.DeepCopy(sourceActor.Geometry.GetMapper().GetInput()); // Mapper vtkDataSetMapper mapper = vtkDataSetMapper.New(); mapper.SetInput(polyData); _geometryMapper = mapper; // Actor _geometry.SetMapper(_geometryMapper); _geometry.GetProperty().DeepCopy(sourceActor.GeometryProperty); _geometryProperty = _geometry.GetProperty(); //_geometry.GetProperty().SetLineWidth(sourceActor.Geometry.GetProperty().GetLineWidth()); _geometry.SetVisibility(sourceActor.Geometry.GetVisibility()); _geometry.SetPickable(sourceActor.Geometry.GetPickable()); // Cell Locator if (sourceActor.CellLocator != null) { _cellLocator = vtkCellLocator.New(); _cellLocator.SetDataSet(_geometryMapper.GetInputAsDataSet()); _cellLocator.LazyEvaluationOn(); } // Frustum Locator if (sourceActor.FrustumCellLocator != null) { vtkUnstructuredGrid grid = vtkUnstructuredGrid.New(); grid.DeepCopy(sourceActor.FrustumCellLocator.GetDataSet()); // _frustumCellLocator = vtkCellLocator.New(); _frustumCellLocator.SetDataSet(grid); _frustumCellLocator.LazyEvaluationOn(); } // Element edges if (sourceActor.ElementEdges != null) { // Poly data polyData = vtkPolyData.New(); polyData.DeepCopy(sourceActor.ElementEdges.GetMapper().GetInput()); // Mapper mapper = vtkDataSetMapper.New(); mapper.SetInput(polyData); // Actor _elementEdges = new vtkActor(); _elementEdges.SetMapper(mapper); _elementEdges.GetProperty().DeepCopy(sourceActor.ElementEdges.GetProperty()); _elementEdges.SetVisibility(sourceActor.ElementEdges.GetVisibility()); _elementEdges.SetPickable(sourceActor.ElementEdges.GetPickable()); // _elementEdgesProperty = _elementEdges.GetProperty(); } // Model edges if (sourceActor.ModelEdges != null) { // Poly data polyData = vtkPolyData.New(); polyData.DeepCopy(sourceActor.ModelEdges.GetMapper().GetInput()); // Mapper mapper = vtkDataSetMapper.New(); mapper.SetInput(polyData); // Actor _modelEdges = vtkActor.New(); _modelEdges.SetMapper(mapper); _modelEdges.GetProperty().DeepCopy(sourceActor.ModelEdges.GetProperty()); _modelEdges.SetVisibility(sourceActor.ModelEdges.GetVisibility()); _modelEdges.SetPickable(sourceActor.ModelEdges.GetPickable()); // _modelEdgesProperty = _modelEdges.GetProperty(); } // Section view _sectionViewActor = sourceActor.SectionViewActor; // transformed copies _copies = new List(sourceActor.Copies); // _isAPart = sourceActor.IsAPart; _actorRepresentation = sourceActor.ActorRepresentation; VtkMaxActorVisible = sourceActor.VtkMaxActorVisible; _backfaceCulling = sourceActor.BackfaceCulling; _color = sourceActor.Color; _backfaceColor = sourceActor.BackfaceColor; _colorTable = sourceActor.ColorTable; _ambient = sourceActor.Ambient; _diffuse = sourceActor.Diffuse; _colorContours = sourceActor.ColorContours; _sectionViewPossible = sourceActor.SectionViewPossible; _drawOnGeometry = sourceActor.DrawOnGeometry; _useSecondaryHighlightColor = sourceActor.UseSecondaryHighlightColor; // _canHaveElementEdges = sourceActor.CanHaveElementEdges; _layer = sourceActor.Layer; // UpdateColor(); } // Methods public void CropWithCylinder(double r, string fileName) { vtkTransform transformCylinder = vtkTransform.New(); transformCylinder.Identity(); //transformCylinder.Translate(-.4, .4, 0); //transformCylinder.RotateZ(30); //transformCylinder.RotateY(60); transformCylinder.RotateX(90); //transformCylinder.Inverse(); vtkCylinder cylinder = vtkCylinder.New(); cylinder.SetTransform(transformCylinder); cylinder.SetRadius(r); // vtkClipPolyData clipper = vtkClipPolyData.New(); clipper.SetInput(_geometryMapper.GetInput()); clipper.SetClipFunction(cylinder); clipper.GenerateClippedOutputOn(); clipper.GenerateClipScalarsOn(); clipper.SetValue(0); // vtkDecimatePro decimate = vtkDecimatePro.New(); decimate.SetInput(clipper.GetClippedOutput()); decimate.SetTargetReduction(0.05); decimate.PreserveTopologyOn(); decimate.Update(); // vtkSTLWriter stlWriter = vtkSTLWriter.New(); stlWriter.SetFileName(fileName); stlWriter.SetInput(decimate.GetOutput()); stlWriter.Write(); } public void CropWithCube(double a, string fileName) { vtkBox box = vtkBox.New(); box.SetBounds(0, a, 0, a, -100 * a, 200 * a); // vtkClipPolyData clipper = vtkClipPolyData.New(); clipper.SetInput(_geometryMapper.GetInput()); clipper.SetClipFunction(box); clipper.GenerateClippedOutputOn(); clipper.GenerateClipScalarsOn(); clipper.SetValue(0); // vtkDecimatePro decimate = vtkDecimatePro.New(); decimate.SetInput(clipper.GetClippedOutput()); decimate.SetTargetReduction(0.05); decimate.PreserveTopologyOn(); decimate.Update(); // vtkSTLWriter stlWriter = vtkSTLWriter.New(); stlWriter.SetFileName(fileName); stlWriter.SetInput(decimate.GetOutput()); stlWriter.Write(); } public void Smooth(double a, string fileName) { vtkWindowedSincPolyDataFilter smoother = vtkWindowedSincPolyDataFilter.New(); // if (true) { int smoothingIterations = 20; double passBand = 0.1; double featureAngle = 360.0; // smoother.SetInput(_geometryMapper.GetInput()); smoother.NormalizeCoordinatesOn(); smoother.SetNumberOfIterations(smoothingIterations); //smoother.BoundarySmoothingOff(); smoother.BoundarySmoothingOn(); smoother.FeatureEdgeSmoothingOn(); //smoother.FeatureEdgeSmoothingOn(); smoother.SetFeatureAngle(featureAngle); smoother.SetPassBand(passBand); smoother.NonManifoldSmoothingOn(); //smoother.NormalizeCoordinatesOn(); smoother.Update(); } if (false) { vtkSmoothPolyDataFilter smoothFilter = vtkSmoothPolyDataFilter.New(); smoothFilter.SetInput(_geometryMapper.GetInput()); smoothFilter.SetNumberOfIterations(15); smoothFilter.SetRelaxationFactor(0.1); smoothFilter.FeatureEdgeSmoothingOff(); smoothFilter.BoundarySmoothingOn(); smoothFilter.Update(); } // vtkDecimatePro decimate = vtkDecimatePro.New(); decimate.SetInput(smoother.GetOutput()); decimate.PreserveTopologyOff(); decimate.SetTargetReduction(0.95); decimate.SplittingOn(); decimate.BoundaryVertexDeletionOn(); decimate.PreserveTopologyOff(); decimate.Update(); // // vtkSTLWriter stlWriter = vtkSTLWriter.New(); stlWriter.SetFileName(fileName); stlWriter.SetInput(smoother.GetOutput()); stlWriter.Write(); } private void AddCellDataToGrid(vtkUnstructuredGrid source, vtkUnstructuredGrid uGridActor, vtkUnstructuredGrid uGridEdges) { int cellType; bool isEdge; vtkIdList list = vtkIdList.New(); // uGridActor.ShallowCopy(source); // vtkUnsignedCharArray types = source.GetCellTypesArray(); // for (int i = 0; i < types.GetNumberOfTuples(); i++) { cellType = (int)types.GetTuple1(i); isEdge = cellType == (int)vtkCellType.VTK_LINE || cellType == (int)vtkCellType.VTK_QUADRATIC_EDGE; // if (!isEdge) { source.GetCellPoints(i, list); uGridEdges.InsertNextCell(cellType, list); } } } private vtkActor GetActorEdgesFromGridByVisualizationSurfaceExtraction(vtkUnstructuredGrid uGridEdges) { if (uGridEdges.GetNumberOfCells() <= 0) return null; // Extract visualization surface of the unstructured grid vtkUnstructuredGridGeometryFilter filter = vtkUnstructuredGridGeometryFilter.New(); filter.SetInput(uGridEdges); filter.Update(); // Extract edges of the visualization surface vtkExtractEdges extractEdges = vtkExtractEdges.New(); extractEdges.SetInput(uGridEdges); extractEdges.Update(); // vtkPolyDataMapper mapper = vtkPolyDataMapper.New(); mapper.SetInput(extractEdges.GetOutput()); // vtkActor edges = vtkActor.New(); edges.SetMapper(mapper); edges.PickableOff(); // return edges; } // public void CreateNodalActor(vtkMaxActorData data) { // Create the geometry of a point (the coordinate) vtkPoints points = vtkPoints.New(); // Create the topology of the point (a vertex) vtkCellArray vertices = vtkCellArray.New(); for (int i = 0; i < data.Geometry.Nodes.Coor.GetLength(0); i++) { points.InsertNextPoint(data.Geometry.Nodes.Coor[i][0], data.Geometry.Nodes.Coor[i][1], data.Geometry.Nodes.Coor[i][2]); vertices.InsertNextCell(1); vertices.InsertCellPoint(i); } // Create a polyData object vtkPolyData pointsPolyData = vtkPolyData.New(); // Set the points and vertices created as the geometry and topology of the poly data pointsPolyData.SetPoints(points); pointsPolyData.SetVerts(vertices); // Mapper vtkPolyDataMapper mapper = vtkPolyDataMapper.New(); mapper.SetInput(pointsPolyData); _geometryMapper = mapper; // Actor _geometry.SetMapper(_geometryMapper); // _geometryProperty = _geometry.GetProperty(); _geometryProperty.SetColor(data.Color.R / 255d, data.Color.G / 255d, data.Color.B / 255d); } private void CreateFromDataByVisualizationSurfaceExtraction(vtkMaxActorData data) { // Unstructured grid vtkUnstructuredGrid uGridActor; vtkUnstructuredGrid uGridEdges; // bool addBackFace = false; AddNodeAndCellDataToGrid(data.Geometry, out uGridActor, out uGridEdges, false, addBackFace); // Extract visualization surface of the unstructured grid - filter only keeps PedigreeIds and not GlobalIds vtkUnstructuredGridGeometryFilter filter = vtkUnstructuredGridGeometryFilter.New(); filter.SetInput(uGridActor); filter.PassThroughPointIdsOn(); filter.PassThroughCellIdsOn(); filter.Update(); // Mapper vtkDataSetMapper mapper = vtkDataSetMapper.New(); mapper.SetInput(filter.GetOutput()); _geometryMapper = mapper; // Actor _geometry.SetMapper(_geometryMapper); // _geometryProperty = _geometry.GetProperty(); _geometryProperty.SetColor(_color.R / 255d, _color.G / 255d, _color.B / 255d); _geometryProperty.SetOpacity(_color.A / 255d); // if (data.Pickable) _geometry.PickableOn(); else _geometry.PickableOff(); // Edges if (data.CanHaveElementEdges) { _elementEdges = GetActorEdgesFromGridByVisualizationSurfaceExtraction(uGridEdges); _elementEdgesProperty = _elementEdges.GetProperty(); } } private void CreatePolyFromData(vtkMaxActorData data) { // Poly data actor vtkPolyData polyActor; vtkPolyData polyEdges; // int[] numOfCellPolys; AddNodeAndCellDataToPoly(data.Geometry, out polyActor, out polyEdges, out numOfCellPolys, true); // Add node scalars if (data.Geometry.Nodes.Values != null) { vtkFloatArray scalars = vtkFloatArray.New(); scalars.SetName(Globals.ScalarArrayName); scalars.SetNumberOfValues(data.Geometry.Nodes.Values.Length); for (int i = 0; i < data.Geometry.Nodes.Values.Length; i++) { scalars.SetValue(i, data.Geometry.Nodes.Values[i]); } // Set scalars polyActor.GetPointData().SetScalars(scalars); // Set extreme nodes data if (data.Geometry.ExtremeNodes.Ids != null) { _minNode = new vtkMaxExtreemeNode(data.Geometry.ExtremeNodes.Ids[0], data.Geometry.ExtremeNodes.Coor[0], data.Geometry.ExtremeNodes.Values[0]); _maxNode = new vtkMaxExtreemeNode(data.Geometry.ExtremeNodes.Ids[1], data.Geometry.ExtremeNodes.Coor[1], data.Geometry.ExtremeNodes.Values[1]); } } // Add cell scalars if (data.Geometry.Cells.Values != null) { // Set scalars float value; vtkFloatArray cellData = vtkFloatArray.New(); for (int i = 0; i < data.Geometry.Cells.Values.Length; i++) { value = data.Geometry.Cells.Values[i]; for (int j = 0; j < numOfCellPolys[i]; j++) cellData.InsertNextValue(value); } polyActor.GetCellData().SetScalars(cellData); } // Actor // Poly data vtkPolyData polyData = polyActor; // Smoothing //vtkLoopSubdivisionFilter subdivisionFilter = vtkLoopSubdivisionFilter.New(); //subdivisionFilter.SetInput(polyData); //subdivisionFilter.SetNumberOfSubdivisions(2); //subdivisionFilter.Update(); //polyData = subdivisionFilter.GetOutput(); polyData.GetPointData().CopyScalarsOn(); // Normals data.SmoothShaded = true; if (data.SmoothShaded) polyData.GetPointData().SetNormals(ComputeNormals(polyData)); // Mapper vtkDataSetMapper mapper = vtkDataSetMapper.New(); mapper.SetInput(polyData); _geometryMapper = mapper; // Actor _geometry.SetMapper(_geometryMapper); _geometryPointData = polyData.GetPointData(); // if (data.Pickable) _geometry.PickableOn(); else _geometry.PickableOff(); // _geometryProperty = _geometry.GetProperty(); // Frustum locator //if (data.Layer == vtkRendererLayer.Base && data.Pickable && data.CellLocator != null) if (data.Layer == vtkRendererLayer.Base && data.CellLocator != null) { vtkUnstructuredGrid uGridCellLocator; // AddNodeAndCellDataToGrid(data.CellLocator, out uGridCellLocator); // _frustumCellLocator = vtkCellLocator.New(); _frustumCellLocator.SetDataSet(uGridCellLocator); _frustumCellLocator.LazyEvaluationOn(); _frustumCellLocator.GetDataSet().GetPointData().SetGlobalIds((vtkUnsignedLongArray)uGridCellLocator.GetPointData().GetGlobalIds()); _frustumCellLocator.GetDataSet().GetCellData().SetGlobalIds((vtkUnsignedLongArray)uGridCellLocator.GetCellData().GetGlobalIds()); // Add scalars if (data.CellLocator.Nodes.Values != null) { vtkFloatArray scalars = vtkFloatArray.New(); scalars.SetName(Globals.ScalarArrayName); scalars.SetNumberOfValues(data.CellLocator.Nodes.Values.Length); for (int i = 0; i < data.CellLocator.Nodes.Values.Length; i++) { scalars.SetValue(i, data.CellLocator.Nodes.Values[i]); } // Set scalars _frustumPointData = _frustumCellLocator.GetDataSet().GetPointData(); _frustumPointData.SetScalars(scalars); } } // Element edges if (data.CanHaveElementEdges) { // Mapper mapper = vtkDataSetMapper.New(); mapper.SetInput(polyEdges); // Actor _elementEdges = new vtkActor(); _elementEdges.SetMapper(mapper); _elementEdges.PickableOff(); // _elementEdgesProperty = _elementEdges.GetProperty(); _elementEdgesProperty.SetLighting(true); } // Model edges if (data.ModelEdges != null) { AddNodeAndCellDataToPoly(data.ModelEdges, out polyActor, out _, out _, false); // Poly data polyData = polyActor; // Mapper mapper = vtkDataSetMapper.New(); mapper.SetInput(polyData); // Actor _modelEdges = vtkActor.New(); _modelEdges.SetMapper(mapper); _modelEdges.PickableOff(); // _modelEdgesProperty = _modelEdges.GetProperty(); _modelEdgesProperty.SetLighting(true); // if (!data.CanHaveElementEdges) { // Recreate data polyData.DeepCopy(polyData); // Mapper mapper = vtkDataSetMapper.New(); mapper.SetInput(polyData); // Actor _elementEdges = new vtkActor(); _elementEdges.SetMapper(mapper); _elementEdges.PickableOff(); // _elementEdgesProperty = _elementEdges.GetProperty(); _elementEdgesProperty.SetLighting(true); } } // Nodes if (false) { // Create the geometry of a point (the coordinate) vtkPoints points = vtkPoints.New(); // Create the topology of the point (a vertex) vtkCellArray vertices = vtkCellArray.New(); for (int i = 0; i < data.Geometry.Nodes.Coor.Length; i++) { points.InsertNextPoint(data.Geometry.Nodes.Coor[i][0], data.Geometry.Nodes.Coor[i][1], data.Geometry.Nodes.Coor[i][2]); vertices.InsertNextCell(1); vertices.InsertCellPoint(i); } // Create a polyData object vtkPolyData pointsPolyData = vtkPolyData.New(); // Set the points and vertices created as the geometry and topology of the poly data pointsPolyData.SetPoints(points); pointsPolyData.SetVerts(vertices); // Mapper mapper = vtkDataSetMapper.New(); mapper.SetInput(pointsPolyData); // Actor _nodes = new vtkActor(); _nodes.SetMapper(mapper); // _nodesProperty = _nodes.GetProperty(); _nodesProperty.SetColor(data.Color.R / 255d, data.Color.G / 255d, data.Color.B / 255d); } } // private void AddNodeAndCellDataToGrid(PartExchangeData data, out vtkUnstructuredGrid uGridActor) { AddNodeAndCellDataToGrid(data, out uGridActor, out _, false, false); } private void AddNodeAndCellDataToGrid(PartExchangeData data, out vtkUnstructuredGrid uGridActor, out vtkUnstructuredGrid uGridEdges, bool extractEdges, bool addBackFace) { // Unstructured grid uGridActor = vtkUnstructuredGrid.New(); uGridEdges = vtkUnstructuredGrid.New(); // Add the points vtkPoints points = vtkPoints.New(); points.SetNumberOfPoints(data.Nodes.Coor.Length); for (int i = 0; i < data.Nodes.Coor.Length; i++) { points.SetPoint(i, data.Nodes.Coor[i][0], data.Nodes.Coor[i][1], data.Nodes.Coor[i][2]); } uGridActor.SetPoints(points); uGridEdges.SetPoints(points); // Add the cells AddCellDataToGrid(data, ref uGridActor, ref uGridEdges, extractEdges, addBackFace); // Add node ids to points in the grid if (data.Nodes.Ids != null) { vtkUnsignedLongArray pointIds = vtkUnsignedLongArray.New(); pointIds.SetNumberOfValues(data.Nodes.Ids.Length); for (int i = 0; i < data.Nodes.Ids.Length; i++) { pointIds.SetValue(i, (uint)data.Nodes.Ids[i]); } uGridActor.GetPointData().SetGlobalIds(pointIds); } // Add cell ids to cells in the grid if (data.Cells.Ids != null) { vtkUnsignedLongArray cellIds = vtkUnsignedLongArray.New(); cellIds.SetNumberOfValues(data.Cells.Ids.Length); for (int i = 0; i < data.Cells.Ids.Length; i++) { cellIds.SetValue(i, (uint)data.Cells.Ids[i]); } uGridActor.GetCellData().SetGlobalIds(cellIds); } // Update grid uGridActor.Update(); uGridEdges.Update(); } private static void AddNodeAndCellDataToPoly(PartExchangeData data, out vtkPolyData polyActor, out vtkPolyData polyEdges, out int[] numOfCellPolys, bool extractEdges) { polyActor = vtkPolyData.New(); polyEdges = vtkPolyData.New(); // Add the points vtkPoints points = vtkPoints.New(); points.SetNumberOfPoints(data.Nodes.Coor.Length); for (int i = 0; i < data.Nodes.Coor.Length; i++) { points.SetPoint(i, data.Nodes.Coor[i][0], data.Nodes.Coor[i][1], data.Nodes.Coor[i][2]); } polyActor.SetPoints(points); polyEdges.SetPoints(points); // Add the cells AddCellDataToPoly(data, ref polyActor, ref polyEdges, out numOfCellPolys, extractEdges); // Add node ids to points in the grid if (data.Nodes.Ids != null) { vtkUnsignedLongArray pointIds = vtkUnsignedLongArray.New(); pointIds.SetNumberOfValues(data.Nodes.Ids.Length); for (int i = 0; i < data.Nodes.Ids.Length; i++) { pointIds.SetValue(i, (uint)data.Nodes.Ids[i]); } polyActor.GetPointData().SetGlobalIds(pointIds); } // Add cell ids to cells in the grid if (data.Cells.Ids != null) { uint id; vtkUnsignedLongArray cellIds = vtkUnsignedLongArray.New(); //cellIds.SetNumberOfValues(data.Cells.Ids.Length); for (int i = 0; i < data.Cells.Ids.Length; i++) { id = (uint)data.Cells.Ids[i]; for (int j = 0; j < numOfCellPolys[i]; j++) cellIds.InsertNextValue(id); } polyActor.GetCellData().SetGlobalIds(cellIds); } // Update grid polyActor.Update(); polyEdges.Update(); } private void AddCellDataToGrid(PartExchangeData data, ref vtkUnstructuredGrid uGridActor, ref vtkUnstructuredGrid uGridEdges, bool extractEdges, bool addBackFace) { int[] nodeIds; int cellType; bool isEdge; bool isSurface; vtkIdList nodeList = vtkIdList.New(); vtkIdList edgeNodeList = vtkIdList.New(); List actorCellIds = new List(); for (int i = 0; i < data.Cells.CellNodeIds.GetLength(0); i++) { nodeIds = data.Cells.CellNodeIds[i]; cellType = data.Cells.Types[i]; isEdge = cellType == (int)vtkCellType.VTK_LINE || cellType == (int)vtkCellType.VTK_QUADRATIC_EDGE; isSurface = cellType == (int)vtkCellType.VTK_TRIANGLE || cellType == (int)vtkCellType.VTK_QUAD || cellType == (int)vtkCellType.VTK_QUADRATIC_TRIANGLE || cellType == (int)vtkCellType.VTK_QUADRATIC_QUAD; // Node list nodeList.SetNumberOfIds(nodeIds.Length); for (int j = 0; j < nodeIds.Length; j++) nodeList.SetId(j, nodeIds[j]); // Cell edges if (!isEdge && uGridEdges != null) { if (!extractEdges) uGridEdges.InsertNextCell(cellType, nodeList); else { if (cellType == (int)vtkCellType.VTK_TRIANGLE) { edgeNodeList.SetNumberOfIds(2); for (int j = 0; j < 3; j++) { edgeNodeList.SetId(0, nodeIds[j]); edgeNodeList.SetId(1, nodeIds[(j + 1) % 3]); uGridEdges.InsertNextCell((int)vtkCellType.VTK_LINE, edgeNodeList); } } else if (cellType == (int)vtkCellType.VTK_QUAD) { edgeNodeList.SetNumberOfIds(2); for (int j = 0; j < 4; j++) { edgeNodeList.SetId(0, nodeIds[j]); edgeNodeList.SetId(1, nodeIds[(j + 1) % 4]); uGridEdges.InsertNextCell((int)vtkCellType.VTK_LINE, edgeNodeList); } } else if (cellType == (int)vtkCellType.VTK_QUADRATIC_TRIANGLE) { edgeNodeList.SetNumberOfIds(3); for (int j = 0; j < 3; j++) { edgeNodeList.SetId(0, nodeIds[j]); edgeNodeList.SetId(1, nodeIds[(j + 1) % 3]); edgeNodeList.SetId(2, nodeIds[j + 3]); uGridEdges.InsertNextCell((int)vtkCellType.VTK_QUADRATIC_EDGE, edgeNodeList); } } else if (cellType == (int)vtkCellType.VTK_QUADRATIC_QUAD) { edgeNodeList.SetNumberOfIds(3); for (int j = 0; j < 4; j++) { edgeNodeList.SetId(0, nodeIds[j]); edgeNodeList.SetId(1, nodeIds[(j + 1) % 4]); edgeNodeList.SetId(2, nodeIds[j + 4]); uGridEdges.InsertNextCell((int)vtkCellType.VTK_QUADRATIC_EDGE, edgeNodeList); } } } } // Cells uGridActor.InsertNextCell(cellType, nodeList); if (data.Cells.Ids != null) actorCellIds.Add(data.Cells.Ids[i]); // Cells backface if (isSurface && addBackFace) { nodeList.SetNumberOfIds(nodeIds.Length); if (cellType == (int)vtkCellType.VTK_TRIANGLE) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[2]); nodeList.SetId(2, nodeIds[1]); } else if (cellType == (int)vtkCellType.VTK_QUAD) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[3]); nodeList.SetId(2, nodeIds[2]); nodeList.SetId(3, nodeIds[1]); } else if (cellType == (int)vtkCellType.VTK_QUADRATIC_TRIANGLE) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[2]); nodeList.SetId(2, nodeIds[1]); nodeList.SetId(3, nodeIds[5]); nodeList.SetId(4, nodeIds[4]); nodeList.SetId(5, nodeIds[3]); } else if (cellType == (int)vtkCellType.VTK_QUADRATIC_QUAD) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[3]); nodeList.SetId(2, nodeIds[2]); nodeList.SetId(3, nodeIds[1]); nodeList.SetId(4, nodeIds[7]); nodeList.SetId(5, nodeIds[6]); nodeList.SetId(6, nodeIds[5]); nodeList.SetId(7, nodeIds[4]); } else throw new NotSupportedException(); uGridActor.InsertNextCell(cellType, nodeList); if (data.Cells.Ids != null) actorCellIds.Add(data.Cells.Ids[i]); } } if (data.Cells.Ids != null) data.Cells.Ids = actorCellIds.ToArray(); } private static void AddCellDataToPoly_(PartExchangeData data, ref vtkPolyData polyActor, ref vtkPolyData polyEdges, out int[] numOfCellPolys, bool extractEdges) { double d1; double d2; // int[] nodeIds; double[][] nodeCoor; int cellType; bool isVertex; bool isEdge; bool isSurface; vtkIdList nodeList = vtkIdList.New(); vtkIdList edgeNodeList = vtkIdList.New(); // numOfCellPolys = null; if (data.Cells.Ids != null) { numOfCellPolys = new int[data.Cells.Ids.Length]; } // int vertexType = (int)vtkCellType.VTK_VERTEX; int lineType = (int)vtkCellType.VTK_LINE; int quadraticEdgeType = (int)vtkCellType.VTK_QUADRATIC_EDGE; int triangleType = (int)vtkCellType.VTK_TRIANGLE; int quadType = (int)vtkCellType.VTK_QUAD; int quadraticTriangleType = (int)vtkCellType.VTK_QUADRATIC_TRIANGLE; int quadraticQuadType = (int)vtkCellType.VTK_QUADRATIC_QUAD; // polyActor.Allocate(10000, 10000); if (extractEdges) polyEdges.Allocate(1000, 1000); // for (int i = 0; i < data.Cells.CellNodeIds.Length; i++) { nodeIds = data.Cells.CellNodeIds[i]; cellType = data.Cells.Types[i]; isVertex = cellType == vertexType; isEdge = cellType == lineType || cellType == quadraticEdgeType; isSurface = cellType == triangleType || cellType == quadType || cellType == quadraticTriangleType || cellType == quadraticQuadType; // Cell edges if (extractEdges) { if (isEdge) { edgeNodeList.SetNumberOfIds(1); //if (cellType == lineType || cellType == quadraticEdgeType) { edgeNodeList.SetId(0, nodeIds[0]); polyEdges.InsertNextCell(vertexType, edgeNodeList); edgeNodeList.SetId(0, nodeIds[1]); polyEdges.InsertNextCell(vertexType, edgeNodeList); } } else if (isSurface) { edgeNodeList.SetNumberOfIds(2); if (cellType == triangleType) { for (int j = 0; j < 3; j++) { edgeNodeList.SetId(0, nodeIds[j]); edgeNodeList.SetId(1, nodeIds[(j + 1) % 3]); polyEdges.InsertNextCell(lineType, edgeNodeList); } } else if (cellType == quadType) { for (int j = 0; j < 4; j++) { edgeNodeList.SetId(0, nodeIds[j]); edgeNodeList.SetId(1, nodeIds[(j + 1) % 4]); polyEdges.InsertNextCell(lineType, edgeNodeList); } } else if (cellType == quadraticTriangleType) { for (int j = 0; j < 3; j++) { edgeNodeList.SetId(0, nodeIds[j]); edgeNodeList.SetId(1, nodeIds[j + 3]); polyEdges.InsertNextCell(lineType, edgeNodeList); edgeNodeList.SetId(0, nodeIds[j + 3]); edgeNodeList.SetId(1, nodeIds[(j + 1) % 3]); polyEdges.InsertNextCell(lineType, edgeNodeList); } } else if (cellType == quadraticQuadType) { for (int j = 0; j < 4; j++) { edgeNodeList.SetId(0, nodeIds[j]); edgeNodeList.SetId(1, nodeIds[j + 4]); polyEdges.InsertNextCell(lineType, edgeNodeList); edgeNodeList.SetId(0, nodeIds[j + 4]); edgeNodeList.SetId(1, nodeIds[(j + 1) % 4]); polyEdges.InsertNextCell(lineType, edgeNodeList); } } } } // Cells if (isVertex) { nodeList.SetNumberOfIds(1); //if (cellType == vertexType) { nodeList.SetId(0, nodeIds[0]); polyActor.InsertNextCell(vertexType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 1; } } else if (isEdge) { nodeList.SetNumberOfIds(2); if (cellType == lineType) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[1]); polyActor.InsertNextCell(lineType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 1; } else if (cellType == quadraticEdgeType) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[2]); polyActor.InsertNextCell(lineType, nodeList); nodeList.SetId(0, nodeIds[2]); nodeList.SetId(1, nodeIds[1]); polyActor.InsertNextCell(lineType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 2; } } else if (isSurface) { nodeList.SetNumberOfIds(3); if (cellType == triangleType) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[1]); nodeList.SetId(2, nodeIds[2]); polyActor.InsertNextCell(triangleType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 1; } else if (cellType == quadType) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[1]); nodeList.SetId(2, nodeIds[2]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[2]); nodeList.SetId(2, nodeIds[3]); polyActor.InsertNextCell(triangleType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 2; } else if (cellType == quadraticTriangleType) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[3]); nodeList.SetId(2, nodeIds[5]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[3]); nodeList.SetId(1, nodeIds[4]); nodeList.SetId(2, nodeIds[5]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[3]); nodeList.SetId(1, nodeIds[1]); nodeList.SetId(2, nodeIds[4]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[5]); nodeList.SetId(1, nodeIds[4]); nodeList.SetId(2, nodeIds[2]); polyActor.InsertNextCell(triangleType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 4; } else if (cellType == quadraticQuadType) { nodeCoor = data.Nodes.Coor; d1 = Vec3D.GetDirVec(nodeCoor[nodeIds[4]], nodeCoor[nodeIds[6]]).Len2; d2 = Vec3D.GetDirVec(nodeCoor[nodeIds[5]], nodeCoor[nodeIds[7]]).Len2; if (d1 < d2) { nodeList.SetId(0, nodeIds[7]); nodeList.SetId(1, nodeIds[0]); nodeList.SetId(2, nodeIds[4]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[7]); nodeList.SetId(1, nodeIds[4]); nodeList.SetId(2, nodeIds[6]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[7]); nodeList.SetId(1, nodeIds[6]); nodeList.SetId(2, nodeIds[3]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[5]); nodeList.SetId(1, nodeIds[4]); nodeList.SetId(2, nodeIds[1]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[5]); nodeList.SetId(1, nodeIds[6]); nodeList.SetId(2, nodeIds[4]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[5]); nodeList.SetId(1, nodeIds[2]); nodeList.SetId(2, nodeIds[6]); polyActor.InsertNextCell(triangleType, nodeList); } else { nodeList.SetId(0, nodeIds[4]); nodeList.SetId(1, nodeIds[7]); nodeList.SetId(2, nodeIds[0]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[4]); nodeList.SetId(1, nodeIds[5]); nodeList.SetId(2, nodeIds[7]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[4]); nodeList.SetId(1, nodeIds[1]); nodeList.SetId(2, nodeIds[5]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[6]); nodeList.SetId(1, nodeIds[5]); nodeList.SetId(2, nodeIds[2]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[6]); nodeList.SetId(1, nodeIds[7]); nodeList.SetId(2, nodeIds[5]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[6]); nodeList.SetId(1, nodeIds[3]); nodeList.SetId(2, nodeIds[7]); polyActor.InsertNextCell(triangleType, nodeList); } if (numOfCellPolys != null) numOfCellPolys[i] = 6; } else throw new NotSupportedException(); } else throw new NotSupportedException(); } // polyActor.Squeeze(); if (extractEdges) polyEdges.Squeeze(); } private static void AddCellDataToPoly(PartExchangeData data, ref vtkPolyData polyActor, ref vtkPolyData polyEdges, out int[] numOfCellPolys, bool extractEdges) { double d1; double d2; // int[] nodeIds; double[][] nodeCoor; int cellType; bool isVertex; bool isEdge; bool isSurface; vtkIdList nodeList = vtkIdList.New(); vtkIdList edgeNodeList = vtkIdList.New(); // numOfCellPolys = null; if (data.Cells.Ids != null) { numOfCellPolys = new int[data.Cells.Ids.Length]; } // int vertexType = (int)vtkCellType.VTK_VERTEX; int lineType = (int)vtkCellType.VTK_LINE; int polyLineType = (int)vtkCellType.VTK_POLY_LINE; int quadraticEdgeType = (int)vtkCellType.VTK_QUADRATIC_EDGE; int triangleType = (int)vtkCellType.VTK_TRIANGLE; int quadType = (int)vtkCellType.VTK_QUAD; int quadraticTriangleType = (int)vtkCellType.VTK_QUADRATIC_TRIANGLE; int quadraticQuadType = (int)vtkCellType.VTK_QUADRATIC_QUAD; // polyActor.Allocate(10000, 10000); if (extractEdges) polyEdges.Allocate(1000, 1000); // int id1; int id2; int id3; HashSet uniqueVertexIds = new HashSet(); HashSet uniqueEdgeCells = new HashSet(); HashSet uniquePolyEdgeCells = new HashSet(); // for (int i = 0; i < data.Cells.CellNodeIds.Length; i++) { nodeIds = data.Cells.CellNodeIds[i]; cellType = data.Cells.Types[i]; isVertex = cellType == vertexType; isEdge = cellType == lineType || cellType == quadraticEdgeType; isSurface = cellType == triangleType || cellType == quadType || cellType == quadraticTriangleType || cellType == quadraticQuadType; // Cell edges if (extractEdges) { if (isEdge) { uniqueVertexIds.UnionWith(nodeIds); } else if (isSurface) { if (cellType == triangleType) { for (int j = 0; j < 3; j++) { id1 = nodeIds[j]; id2 = nodeIds[(j + 1) % 3]; uniqueEdgeCells.Add(new int[] { Math.Min(id1, id2), Math.Max(id1, id2) }); } } else if (cellType == quadType) { for (int j = 0; j < 4; j++) { id1 = nodeIds[j]; id2 = nodeIds[(j + 1) % 4]; uniqueEdgeCells.Add(new int[] { Math.Min(id1, id2), Math.Max(id1, id2) }); } } else if (cellType == quadraticTriangleType) { for (int j = 0; j < 3; j++) { id1 = nodeIds[j]; id2 = nodeIds[j + 3]; id3 = nodeIds[(j + 1) % 3]; if (id1 < id3) uniquePolyEdgeCells.Add(new int[] { id1, id2, id3 }); else uniquePolyEdgeCells.Add(new int[] { id3, id2, id1 }); } } else if (cellType == quadraticQuadType) { for (int j = 0; j < 4; j++) { id1 = nodeIds[j]; id2 = nodeIds[j + 4]; id3 = nodeIds[(j + 1) % 4]; if (id1 < id3) uniquePolyEdgeCells.Add(new int[] { id1, id2, id3 }); else uniquePolyEdgeCells.Add(new int[] { id3, id2, id1 }); } } } } // Cells if (isVertex) { nodeList.SetNumberOfIds(1); //if (cellType == vertexType) { nodeList.SetId(0, nodeIds[0]); polyActor.InsertNextCell(vertexType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 1; } } else if (isEdge) { nodeList.SetNumberOfIds(2); if (cellType == lineType) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[1]); polyActor.InsertNextCell(lineType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 1; } else if (cellType == quadraticEdgeType) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[2]); polyActor.InsertNextCell(lineType, nodeList); nodeList.SetId(0, nodeIds[2]); nodeList.SetId(1, nodeIds[1]); polyActor.InsertNextCell(lineType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 2; } } else if (isSurface) { nodeList.SetNumberOfIds(3); if (cellType == triangleType) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[1]); nodeList.SetId(2, nodeIds[2]); polyActor.InsertNextCell(triangleType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 1; } else if (cellType == quadType) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[1]); nodeList.SetId(2, nodeIds[2]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[2]); nodeList.SetId(2, nodeIds[3]); polyActor.InsertNextCell(triangleType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 2; } else if (cellType == quadraticTriangleType) { nodeList.SetId(0, nodeIds[0]); nodeList.SetId(1, nodeIds[3]); nodeList.SetId(2, nodeIds[5]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[3]); nodeList.SetId(1, nodeIds[4]); nodeList.SetId(2, nodeIds[5]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[3]); nodeList.SetId(1, nodeIds[1]); nodeList.SetId(2, nodeIds[4]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[5]); nodeList.SetId(1, nodeIds[4]); nodeList.SetId(2, nodeIds[2]); polyActor.InsertNextCell(triangleType, nodeList); if (numOfCellPolys != null) numOfCellPolys[i] = 4; } else if (cellType == quadraticQuadType) { nodeCoor = data.Nodes.Coor; d1 = Vec3D.GetDirVec(nodeCoor[nodeIds[4]], nodeCoor[nodeIds[6]]).Len2; d2 = Vec3D.GetDirVec(nodeCoor[nodeIds[5]], nodeCoor[nodeIds[7]]).Len2; if (d1 < d2) { nodeList.SetId(0, nodeIds[7]); nodeList.SetId(1, nodeIds[0]); nodeList.SetId(2, nodeIds[4]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[7]); nodeList.SetId(1, nodeIds[4]); nodeList.SetId(2, nodeIds[6]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[7]); nodeList.SetId(1, nodeIds[6]); nodeList.SetId(2, nodeIds[3]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[5]); nodeList.SetId(1, nodeIds[4]); nodeList.SetId(2, nodeIds[1]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[5]); nodeList.SetId(1, nodeIds[6]); nodeList.SetId(2, nodeIds[4]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[5]); nodeList.SetId(1, nodeIds[2]); nodeList.SetId(2, nodeIds[6]); polyActor.InsertNextCell(triangleType, nodeList); } else { nodeList.SetId(0, nodeIds[4]); nodeList.SetId(1, nodeIds[7]); nodeList.SetId(2, nodeIds[0]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[4]); nodeList.SetId(1, nodeIds[5]); nodeList.SetId(2, nodeIds[7]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[4]); nodeList.SetId(1, nodeIds[1]); nodeList.SetId(2, nodeIds[5]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[6]); nodeList.SetId(1, nodeIds[5]); nodeList.SetId(2, nodeIds[2]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[6]); nodeList.SetId(1, nodeIds[7]); nodeList.SetId(2, nodeIds[5]); polyActor.InsertNextCell(triangleType, nodeList); nodeList.SetId(0, nodeIds[6]); nodeList.SetId(1, nodeIds[3]); nodeList.SetId(2, nodeIds[7]); polyActor.InsertNextCell(triangleType, nodeList); } if (numOfCellPolys != null) numOfCellPolys[i] = 6; } else throw new NotSupportedException(); } else throw new NotSupportedException(); } // if (extractEdges) { edgeNodeList.SetNumberOfIds(1); foreach (var vertexId in uniqueVertexIds) { edgeNodeList.SetId(0, vertexId); polyEdges.InsertNextCell(vertexType, edgeNodeList); } // edgeNodeList.SetNumberOfIds(2); foreach (var edgeCell in uniqueEdgeCells) { edgeNodeList.SetId(0, edgeCell[0]); edgeNodeList.SetId(1, edgeCell[1]); polyEdges.InsertNextCell(lineType, edgeNodeList); } // edgeNodeList.SetNumberOfIds(3); foreach (var polyEdgeCell in uniquePolyEdgeCells) { edgeNodeList.SetId(0, polyEdgeCell[0]); edgeNodeList.SetId(1, polyEdgeCell[1]); edgeNodeList.SetId(2, polyEdgeCell[2]); polyEdges.InsertNextCell(polyLineType, edgeNodeList); } } // polyActor.Squeeze(); if (extractEdges) polyEdges.Squeeze(); } // Color and visuals public virtual void UpdateColor() { double opacity = _color.A / 255d; // Custom coloring of elements: sections, materials... if (_colorTable != null) { // Create color table vtkLookupTable cellLut = vtkLookupTable.New(); cellLut.SetNumberOfTableValues(_colorTable.Length + 1); // +1 for the missing color cellLut.Build(); cellLut.SetTableValue(0, 1, 1, 1, 0.5); // White for missing color for (int i = 0; i < _colorTable.Length; i++) cellLut.SetTableValue(i + 1, _colorTable[i].R / 255d, _colorTable[i].G / 255d, _colorTable[i].B / 255d, 1); //cellLut.SetValueRange(0, _colorTable.Length - 1); // _geometryMapper.SetLookupTable(cellLut); _geometryMapper.SetScalarRange(-1, _colorTable.Length - 1); //_geometryMapper.SetUseLookupTableScalarRange(1); //mapper.SetScalarRange(-1, data.ColorTable.Length - 1); //mapper.SetScalarModeToUseCellData(); //mapper.SetInterpolateScalarsBeforeMapping(1); //mapper.SetColorModeToMapScalars(); // _geometryProperty.SetAmbientColor(0.8, 0.8, 0.8); // also reset part color highlight _geometryProperty.SetAmbient(0.2); _geometryProperty.SetDiffuse(0.201); // must be a little larger // _geometryProperty.SetOpacity(opacity); // This changes the base color and forces graphics update !? _geometryProperty.SetSpecularColor(1, 1, 1); // must be here to enable specular for colorTable _geometryProperty.SetSpecular(0.6); _geometryProperty.SetSpecularPower(100); } else { _geometryProperty.SetAmbient(_ambient); _geometryProperty.SetDiffuse(_diffuse); // _geometryProperty.SetOpacity(opacity); // if (!ColorContours) { _geometryProperty.SetColor(_color.R / 255d, _color.G / 255d, _color.B / 255d); // This changes the base color and forces graphics update !? //_geometryProperty.SetSpecularColor(1, 1, 1); _geometryProperty.SetSpecular(0.6); _geometryProperty.SetSpecularPower(100); } else { // This changes the base color and forces graphics update !? _geometryProperty.SetAmbientColor(1, 1, 1); // also reset part color highlight } } // if (_modelEdges != null) { _modelEdgesProperty.SetColor(0, 0, 0); _modelEdgesProperty.SetLighting(false); _modelEdgesProperty.SetLineWidth(0.8f); _modelEdgesProperty.SetOpacity(opacity * 0.7); } //if (opacity < 1) opacity = Math.Min(0.2, opacity); if (_elementEdges != null) { _elementEdgesProperty.SetColor(0, 0, 0); _elementEdgesProperty.SetLighting(false); _elementEdgesProperty.SetLineWidth(0.5f); _elementEdgesProperty.SetOpacity(opacity * 0.4); } // Backface property if (!_backfaceColor.IsEmpty && !_backfaceCulling) { vtkProperty property = vtkProperty.New(); // property.SetAmbient(_ambient); property.SetDiffuse(_diffuse); // opacity = _backfaceColor.A / 255d; property.SetOpacity(opacity); // if (!ColorContours) { property.SetColor(_backfaceColor.R / 255d, _backfaceColor.G / 255d, _backfaceColor.B / 255d); // This changes the base color and forces graphics update !? //property.SetSpecularColor(1, 1, 1); property.SetSpecular(0.6); property.SetSpecularPower(100); } else { // This changes the base color and forces graphics update !? property.SetAmbientColor(1, 1, 1); // also reset part color highlight } _geometry.SetBackfaceProperty(property); } } public void UpdateVisibility() { // Update even if VtkMaxActorVisible == _visible to set the visibility for the geometry actor VtkMaxActorVisible = _visible; } public void Highlight() { _geometryProperty.SetAmbientColor(1, 0, 0); } private vtkDataArray ComputeNormals(vtkPointSet pointSet) { // Recompute poly data normals vtkPolyDataNormals normalGenerator = vtkPolyDataNormals.New(); normalGenerator.SetInput(pointSet); normalGenerator.SplittingOff(); // prevents changes in topology //normalGenerator.SetFeatureAngle(0.001 * Math.PI / 180); normalGenerator.ComputePointNormalsOn(); normalGenerator.ComputeCellNormalsOff(); normalGenerator.Update(); return normalGenerator.GetOutput().GetPointData().GetNormals(); } // Animation public void SetAnimationFrame(vtkMaxActorData data, int frameNumber) { if (data.Geometry.NodesAnimation != null) { if (frameNumber < 0 || frameNumber >= data.Geometry.NodesAnimation.Length) throw new Exception("The animation frame cannot be set."); // vtkMaxActorAnimationData animationData = new vtkMaxActorAnimationData(data.Geometry.NodesAnimation[frameNumber].Coor, data.ModelEdges.NodesAnimation[frameNumber].Coor, data.Geometry.NodesAnimation[frameNumber].Values, data.Geometry.ExtremeNodesAnimation[frameNumber], data.CellLocator.NodesAnimation[frameNumber].Coor, data.CellLocator.NodesAnimation[frameNumber].Values); // Actor points if (animationData.Points != null) { vtkPointSet pointSet = _geometryMapper.GetInput() as vtkPointSet; pointSet.SetPoints(animationData.Points); (_elementEdges.GetMapper().GetInput() as vtkPointSet).SetPoints(animationData.Points); // Normals if (pointSet.GetPointData().GetNormals() != null && animationData.PointNormals == null) animationData.PointNormals = ComputeNormals(pointSet); pointSet.GetPointData().SetNormals(animationData.PointNormals); } // Actor edges points if (animationData.ModelEdgesPoints != null && _modelEdges != null) (_modelEdges.GetMapper().GetInput() as vtkPointSet).SetPoints(animationData.ModelEdgesPoints); // Values if (animationData.Values != null) _geometryMapper.GetInput().GetPointData().SetScalars(animationData.Values); // Min/max if (animationData.MinNode != null) _minNode = animationData.MinNode; if (animationData.MaxNode != null) _maxNode = animationData.MaxNode; // Locator points if (animationData.LocatorPoints != null) { vtkPointSet pointSet = _frustumCellLocator.GetDataSet() as vtkPointSet; pointSet.SetPoints(animationData.LocatorPoints); } // Locator values if (animationData.LocatorValues != null) _frustumCellLocator.GetDataSet().GetPointData().SetScalars(animationData.LocatorValues); } } // Section cut public void AddClippingPlane(vtkPlane sectionViewPlane) { _geometryMapper.AddClippingPlane(sectionViewPlane); if (ElementEdges != null) ElementEdges.GetMapper().AddClippingPlane(sectionViewPlane); if (ModelEdges != null) ModelEdges.GetMapper().AddClippingPlane(sectionViewPlane); // if (ActorRepresentation == vtkMaxActorRepresentation.SolidAsShell) _geometryProperty.BackfaceCullingOff(); } public void RemoveAllClippingPlanes() { _geometryMapper.RemoveAllClippingPlanes(); if (ElementEdges != null) ElementEdges.GetMapper().RemoveAllClippingPlanes(); if (ModelEdges != null) ModelEdges.GetMapper().RemoveAllClippingPlanes(); } // Exports public double[][][] GetStlTriangles() { vtkCell cell; vtkPoints points; long numOfPoints; long numCells = _geometryMapper.GetInput().GetNumberOfCells(); double[][] triangle; List triangles = new List(); // for (int i = 0; i < numCells; i++) { cell = _geometryMapper.GetInput().GetCell(i); points = cell.GetPoints(); numOfPoints = points.GetNumberOfPoints(); if (numOfPoints == 3) { triangle = new double[3][]; for (int j = 0; j < 3; j++) { triangle[j] = points.GetPoint(j); } triangles.Add(triangle); } else throw new NotSupportedException(); } // return triangles.ToArray(); ; } } }