Operations with Three-Dimensional Grains edit page

The Three-Dimensional EBSD Analysis overview distinguishes volume measurements from the grain3d surface representation. This page shows how to cut those grains into a planar map, replace polygonal faces by triangles, and rotate geometry together with orientation.

The examples use the synthetic tessellation introduced on the Neper Interface page. The preceding Properties of Three-Dimensional Grains page explains the volume, surface, and face properties used below.

plottingConvention.default('y↑→x');

Load the example microstructure

mtexdata NeperGrain3d

plot(grains,grains.meanOrientation,'micronbar','off')
setCamera(plottingConvention.default3D)
grains = grain3d (y↑→x)
 
 Phase  Grains   Volume  Mineral  Symmetry  Crystal reference frame
     2    1000  1000000   Quartz       321        X||a*, Y||b, Z||c
 
 boundary faces: 7203
 
 Properties: meanRotation

Each colour represents the mean orientation of one grain. The outer faces hide most of the grains inside the tessellated volume, which is why a planar section answers a different question from this surface view.

Cut one planar section

Three-Dimensional Grains introduces planar sectioning and the grain2d result. The direct form of slice used here specifies the plane by a normal N and any point P0 in the plane.

% Point through which the plane passes.
P0 = vector3d(50,50,50);

% Plane normal.
N = vector3d(1,-1,1);

grainSlice = grains.slice(N,P0)

plot(grainSlice,grainSlice.meanOrientation,'micronbar','off')
setCamera(plottingConvention.default3D)
grainSlice = grain2d (y↑→x)
 
 Phase  Grains  Pixels  Mineral  Symmetry      Color
     2     183     183   Quartz       321  LightBlue
 
 boundary segments: 552 (3170 µm)
 inner boundary segments: 0 (0 µm)
 triple points: 320
 
 Properties: meanRotation, Id3d

The slice is still drawn in the three-dimensional scene. From the default viewpoint it is seen obliquely. A plotting convention with N pointing out of the screen gives the face-on view a microscope would have.

sectionView = plottingConvention;
sectionView.outOfScreen = N;
sectionView.north = zvector;
setCamera(sectionView)

The polygons are cuts through grains, not complete grains. A grain that is large in this section may occupy little volume, and a large grain can be missed when the plane does not intersect it.

The returned Id3d property records the array position of each parent grain in the original collection. Use it to recover the full polyhedra that produced selected section polygons.

parentIds = unique(grainSlice.Id3d);
parentGrains = grains(parentIds);

newMtexFigure('layout',[1,2]);
plot(grainSlice,grainSlice.meanOrientation,'micronbar','off')
setCamera(sectionView)
mtexTitle('Planar sections')

nextAxis
plot(parentGrains,parentGrains.meanOrientation,'micronbar','off')
setCamera(plottingConvention.default3D)
mtexTitle('Parent grains')

The left panel contains only the section polygons. The right panel shows their parent polyhedra extending on both sides of the cutting plane.

Compare several parallel sections

Several slices require several calls to slice. Drawing horizontal cuts together shows how little of the volume any single section represents.

N = vector3d.Z;
for k = 1:19:99

  grainSlice = grains.slice(N,vector3d(0,0,k));
  plot(grainSlice,grainSlice.meanOrientation)
  % Interactive selection cannot combine grain2d objects from different planes.
  rmappdata(gca,'grains')
  hold on

end
hold off
setCamera(plottingConvention.default3D)

Follow one colour from slice to slice. A grain that is large in one section may be absent from the next.

Triangulate polygonal faces

The faces of these grains are polygons with many vertices. Some computations are much faster on triangles. triangulate returns equivalent grains whose polygonal faces have been divided into triangles.

selectedGrains = grains(20:21);
grainsTri = selectedGrains.triangulate

full([sum(selectedGrains.numFaces), sum(grainsTri.numFaces)])

plot(grainsTri,grainsTri.meanOrientation,'micronbar','off')
setCamera(plottingConvention.default3D)
grainsTri = grain3d (y↑→x)
 
 Phase  Grains  Volume  Mineral  Symmetry  Crystal reference frame
     2       2    2149   Quartz       321        X||a*, Y||b, Z||c
 
 boundary faces: 112
 
 Id   Phase   Pixels             meanRotation
 20       2        1   (305.6°,155.7°,215.9°)
 21       2        1   (330.4°,144.1°,350.9°)
 
ans =
    34   112

The two grains have 34 polygonal faces before triangulation and 112 triangular faces afterwards. The displayed shape is unchanged because the new triangles cover the same boundary polygons. Triangulation changes the mesh representation, not the physical grains or their stored mean orientations.

Rotate geometry and orientation together

rotate turns grains in space. By default it rotates both things a grain carries: its shape and its orientation. Rotating only one of them would describe a different specimen rather than the same specimen seen differently.

rot = rotation.byAxisAngle(vector3d(1,1,1),30*degree);
grainsRotated = rot * grains;

plot(grainsRotated,grainsRotated.meanOrientation,'micronbar','off')
setCamera(plottingConvention.default3D)

The shape has turned about the coordinate origin, and the colours change. An IPF colour says which crystal direction points along a fixed specimen axis. Every mean orientation now differs from its original by exactly the 30 degree rotation. A rigid rotation preserves the relation between the grains, not their relation to the coordinate axes.

The method form provides a 'center' option when the spatial rotation should use a point other than the origin.

rotationCenter = grains.midPoint;
grainsAboutCenter = rotate(grains,rot,'center',rotationCenter);

Rotate only one part of the data

Two flags deliberately decouple geometry from orientation. The names say which values are kept fixed, not which values are rotated.

Flag

Geometry

Mean orientation

'keepEuler'

rotated

unchanged

'keepXY'

unchanged

rotated

For example, the first command below turns the vertices while retaining the orientation values. The second changes the orientations while retaining the vertices.

geometryOnly = rotate(grains,rot,'keepEuler');
orientationOnly = rotate(grains,rot,'keepXY');

These flags are useful when geometry and orientation require separate corrections. They do not represent a rigid rotation of the whole specimen. The 'center' option affects only a spatial rotation, so it has no effect when 'keepXY' leaves the geometry unchanged.

References

Citing this page. This page is part of the documentation of MTEX, a free and open source MATLAB toolbox for analyzing and modeling crystallographic textures. It was written by The MTEX Developers and is published at https://mtex-toolbox.github.io/Grains3DOperations.html. If you use MTEX, or reuse text or figures from this page, in your research, please cite

F. Bachmann, R. Hielscher, H. Schaeben: Texture Analysis with MTEX - Free and Open Source Software Toolbox, Solid State Phenomena 160 (2010), 63-68. 10.4028/www.scientific.net/SSP.160.63

BibTeX
@article{bachmann2010mtex,
  author  = {F. Bachmann and R. Hielscher and H. Schaeben},
  title   = {Texture Analysis with MTEX - Free and Open Source Software Toolbox},
  journal = {Solid State Phenomena},
  volume  = {160},
  pages   = {63-68},
  year    = {2010},
  doi     = {10.4028/www.scientific.net/SSP.160.63},
  url     = {https://doi.org/10.4028/www.scientific.net/SSP.160.63}
}

Other papers describing specific MTEX methods are listed under Publications — please cite the one that best fits your application. The MTEX source code is licensed under the GNU General Public License v2.0; the text and figures of this documentation are licensed under CC BY 4.0, which permits reuse — including by automated systems — provided The MTEX Developers and this page are credited.