-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathExample_MachineScrew.sh
More file actions
executable file
·114 lines (108 loc) · 3.95 KB
/
Copy pathExample_MachineScrew.sh
File metadata and controls
executable file
·114 lines (108 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env bash
# This example demonstrates a non-trivial application of DICOMautomaton for
# performing a difficult boolean operation: generation of a double-threaded
# machine screw, i.e., one that will simultaneously accept both clockwise and
# anti-clockwise nuts.
#
# A double-threaded screw can be generated by computing the boolean intersection
# of a screw with a clockwise thread, and a screw with an anti-clockwise thread.
# A standard M6 machine screw was modeled in a CAD program, and a mirror image
# of the screw mesh was also generated. However, due to numerical inaccuracies,
# boolean operations failed. The mesh was not manifold (i.e., watertight).
#
# Using DICOMautomaton, we can attempt to make the mesh manifold. However, most
# CAD programs cannot (easily) handle surface meshes, so import back into the
# CAD program might not work, and if it does, performing boolean operations
# may be extremely slow. Instead, we can use DICOMautomaton to perform the
# boolean operation and make the finished double-threaded screw.
#
# The basic process is
# 1. load the (non-manifold) surface mesh,
# 2. define an array of intersecting planes (images),
# 3. slice the mesh using the planes, extracting contours,
# 4. mirror the contours,
# 5. for each plane, perform a (2D) boolean operation, and finally
# 6. convert from contours back to mesh by stitching contours back together.
#
# This script performs the above procedure and generates a valid mesh. Note that
# no voxel interpolation is performed. By carefully chosing where to slice, no
# features are lost. Note that both clockwise and anti-clockwise threaded nuts
# can be generated from the input, but are not here for brevity.
#
# Written by Hal Clark, 2021.
#
set -eux
set -o pipefail
# First check if CGAL support is enabled. It is needed for this example.
function skip_example {
echo "CGAL is not available. Skipping example..."
exit 0
}
"${DCMA_BIN}" -u | \
grep 'CGAL[ ]*true' | \
grep . || skip_example
"${DCMA_BIN}" \
"${TEST_FILES_ROOT}"/M6x20_screw_nonmanifold_binary.ply.tgz \
`# ` \
`# Extract contours by slicing the original mesh. ` \
-o GenerateSyntheticImages \
-p ImagePosition='-8,-8,-22' \
-p NumberOfColumns=6 \
-p NumberOfRows=6 \
-p VoxelHeight=5.0 \
-p VoxelWidth=5.0 \
-p NumberOfImages=600 \
-p SliceThickness=0.05 \
-p SpacingBetweenSlices=0.05 \
-o MakeMeshesManifold \
-p MeshSelection='last' \
-p MeshLabel='screw' \
-o ConvertMeshesToContours \
-p ImageSelection='last' \
-p MeshSelection='last' \
-p ROILabel='screw' \
-o DeleteMeshes \
-p MeshSelection='all' \
-x SFML_Viewer \
-x CropImageDoseToROIs \
`# ` \
`# Mirror the contours.` \
`# ` \
`# Note: It is generally better to mirror the mesh, if possible, because ` \
`# they may misalign with the original images. In this there is no ` \
`# risk because we also control the image orientation. ` \
-o CopyContours \
-p ROILabelRegex='screw' \
-p ROILabel='anti' \
-o GenerateWarp \
-p Transforms='mirror(0,0,0, 1,0,0)' \
-o WarpContours \
-p ROILabelRegex='anti' \
-x SFML_Viewer \
`# ` \
`# Perform the per-slice boolean intersection.` \
-o ContourBooleanOperations \
-p ROILabelRegexA='screw' \
-p ROILabelRegexB='anti' \
-p Operation='intersection' \
-p OutputROILabel='dual' \
-x SFML_Viewer \
`# ` \
`# Export a point cloud from the contour vertices.` \
-o ConvertContoursToPoints \
-p ROILabelRegex='dual' \
-p Label='dual' \
-p Method='vertices' \
-o ExportPointClouds \
-p PointSelection='last' \
-p FilenameBase='M6x20_screw_dualthreaded_manifold.xyz' \
`# ` \
`# Export a mesh by stitching together the contours.` \
-o ConvertContoursToMeshes \
-p ROILabelRegex='dual' \
-p MeshLabel='dual' \
-o ExportSurfaceMeshesPLY \
-p MeshSelection='last' \
-p Filename='M6x20_screw_dualthreaded_manifold_binary.ply' \
-p Variant='binary' \
-x SFML_Viewer