three-cad-viewer 2.1.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +3 -2
- package/dist/three-cad-viewer.css +12 -1
- package/dist/three-cad-viewer.esm.js +4653 -2179
- package/dist/three-cad-viewer.esm.min.js +1 -1
- package/dist/three-cad-viewer.js +4653 -2179
- package/dist/three-cad-viewer.min.js +1 -1
- package/package.json +3 -3
- package/src/_version.js +1 -1
- package/src/axes.js +1 -0
- package/src/bbox.js +6 -1
- package/src/cad_tools/measure.js +610 -526
- package/src/cad_tools/tools.js +127 -128
- package/src/cad_tools/ui.js +280 -284
- package/src/camera.js +21 -15
- package/src/clipping.js +274 -89
- package/src/display.js +206 -56
- package/src/font.js +72 -0
- package/src/fontloader/FontLoader.js +107 -140
- package/src/grid.js +90 -14
- package/src/icons.js +0 -2
- package/src/index.html +19 -8
- package/src/nestedgroup.js +115 -53
- package/src/objectgroup.js +20 -12
- package/src/slider.js +1 -1
- package/src/toolbar.js +13 -5
- package/src/treeview.js +11 -1
- package/src/viewer.js +212 -56
|
@@ -1,183 +1,150 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FileLoader,
|
|
3
|
-
Loader,
|
|
4
|
-
ShapePath
|
|
5
|
-
} from 'three';
|
|
1
|
+
import { FileLoader, Loader, ShapePath } from "three";
|
|
6
2
|
|
|
7
3
|
class FontLoader extends Loader {
|
|
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
|
-
return new Font( json );
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
4
|
+
constructor(manager) {
|
|
5
|
+
super(manager);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
load(url, onLoad, onProgress, onError) {
|
|
9
|
+
const scope = this;
|
|
10
|
+
|
|
11
|
+
const loader = new FileLoader(this.manager);
|
|
12
|
+
loader.setPath(this.path);
|
|
13
|
+
loader.setRequestHeader(this.requestHeader);
|
|
14
|
+
loader.setWithCredentials(this.withCredentials);
|
|
15
|
+
loader.load(
|
|
16
|
+
url,
|
|
17
|
+
function (text) {
|
|
18
|
+
const font = scope.parse(JSON.parse(text));
|
|
19
|
+
|
|
20
|
+
if (onLoad) onLoad(font);
|
|
21
|
+
},
|
|
22
|
+
onProgress,
|
|
23
|
+
onError,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
parse(json) {
|
|
28
|
+
return new Font(json);
|
|
29
|
+
}
|
|
39
30
|
}
|
|
40
31
|
|
|
41
32
|
//
|
|
42
33
|
|
|
43
34
|
class Font {
|
|
35
|
+
constructor(data) {
|
|
36
|
+
this.isFont = true;
|
|
44
37
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.isFont = true;
|
|
48
|
-
|
|
49
|
-
this.type = 'Font';
|
|
50
|
-
|
|
51
|
-
this.data = data;
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
generateShapes( text, size = 100 ) {
|
|
56
|
-
|
|
57
|
-
const shapes = [];
|
|
58
|
-
const paths = createPaths( text, size, this.data );
|
|
59
|
-
|
|
60
|
-
for ( let p = 0, pl = paths.length; p < pl; p ++ ) {
|
|
61
|
-
|
|
62
|
-
shapes.push( ...paths[ p ].toShapes() );
|
|
38
|
+
this.type = "Font";
|
|
63
39
|
|
|
64
|
-
|
|
40
|
+
this.data = data;
|
|
41
|
+
}
|
|
65
42
|
|
|
66
|
-
|
|
43
|
+
generateShapes(text, size = 100) {
|
|
44
|
+
const shapes = [];
|
|
45
|
+
const paths = createPaths(text, size, this.data);
|
|
67
46
|
|
|
68
|
-
|
|
47
|
+
for (let p = 0, pl = paths.length; p < pl; p++) {
|
|
48
|
+
shapes.push(...paths[p].toShapes());
|
|
49
|
+
}
|
|
69
50
|
|
|
51
|
+
return shapes;
|
|
52
|
+
}
|
|
70
53
|
}
|
|
71
54
|
|
|
72
|
-
function createPaths(
|
|
55
|
+
function createPaths(text, size, data) {
|
|
56
|
+
const chars = Array.from(text);
|
|
57
|
+
const scale = size / data.resolution;
|
|
58
|
+
const line_height =
|
|
59
|
+
(data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness) *
|
|
60
|
+
scale;
|
|
73
61
|
|
|
74
|
-
|
|
75
|
-
const scale = size / data.resolution;
|
|
76
|
-
const line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;
|
|
62
|
+
const paths = [];
|
|
77
63
|
|
|
78
|
-
|
|
64
|
+
let offsetX = 0,
|
|
65
|
+
offsetY = 0;
|
|
79
66
|
|
|
80
|
-
|
|
67
|
+
for (let i = 0; i < chars.length; i++) {
|
|
68
|
+
const char = chars[i];
|
|
81
69
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
} else {
|
|
92
|
-
|
|
93
|
-
const ret = createPath( char, scale, offsetX, offsetY, data );
|
|
94
|
-
offsetX += ret.offsetX;
|
|
95
|
-
paths.push( ret.path );
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return paths;
|
|
70
|
+
if (char === "\n") {
|
|
71
|
+
offsetX = 0;
|
|
72
|
+
offsetY -= line_height;
|
|
73
|
+
} else {
|
|
74
|
+
const ret = createPath(char, scale, offsetX, offsetY, data);
|
|
75
|
+
offsetX += ret.offsetX;
|
|
76
|
+
paths.push(ret.path);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
102
79
|
|
|
80
|
+
return paths;
|
|
103
81
|
}
|
|
104
82
|
|
|
105
|
-
function createPath(
|
|
106
|
-
|
|
107
|
-
const glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
|
|
108
|
-
|
|
109
|
-
if ( ! glyph ) {
|
|
110
|
-
|
|
111
|
-
console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
|
|
112
|
-
|
|
113
|
-
return;
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const path = new ShapePath();
|
|
118
|
-
|
|
119
|
-
let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
|
|
120
|
-
|
|
121
|
-
if ( glyph.o ) {
|
|
122
|
-
|
|
123
|
-
const outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
|
|
124
|
-
|
|
125
|
-
for ( let i = 0, l = outline.length; i < l; ) {
|
|
126
|
-
|
|
127
|
-
const action = outline[ i ++ ];
|
|
128
|
-
|
|
129
|
-
switch ( action ) {
|
|
130
|
-
|
|
131
|
-
case 'm': // moveTo
|
|
132
|
-
|
|
133
|
-
x = outline[ i ++ ] * scale + offsetX;
|
|
134
|
-
y = outline[ i ++ ] * scale + offsetY;
|
|
83
|
+
function createPath(char, scale, offsetX, offsetY, data) {
|
|
84
|
+
const glyph = data.glyphs[char] || data.glyphs["?"];
|
|
135
85
|
|
|
136
|
-
|
|
86
|
+
if (!glyph) {
|
|
87
|
+
console.error(
|
|
88
|
+
`THREE.Font: character "${char}" does not exists in font family ${data.familyName}`,
|
|
89
|
+
);
|
|
137
90
|
|
|
138
|
-
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
139
93
|
|
|
140
|
-
|
|
94
|
+
const path = new ShapePath();
|
|
141
95
|
|
|
142
|
-
|
|
143
|
-
y = outline[ i ++ ] * scale + offsetY;
|
|
96
|
+
let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
|
|
144
97
|
|
|
145
|
-
|
|
98
|
+
if (glyph.o) {
|
|
99
|
+
const outline =
|
|
100
|
+
glyph._cachedOutline || (glyph._cachedOutline = glyph.o.split(" "));
|
|
146
101
|
|
|
147
|
-
|
|
102
|
+
for (let i = 0, l = outline.length; i < l; ) {
|
|
103
|
+
const action = outline[i++];
|
|
148
104
|
|
|
149
|
-
|
|
105
|
+
switch (action) {
|
|
106
|
+
case "m": // moveTo
|
|
107
|
+
x = outline[i++] * scale + offsetX;
|
|
108
|
+
y = outline[i++] * scale + offsetY;
|
|
150
109
|
|
|
151
|
-
|
|
152
|
-
cpy = outline[ i ++ ] * scale + offsetY;
|
|
153
|
-
cpx1 = outline[ i ++ ] * scale + offsetX;
|
|
154
|
-
cpy1 = outline[ i ++ ] * scale + offsetY;
|
|
110
|
+
path.moveTo(x, y);
|
|
155
111
|
|
|
156
|
-
|
|
112
|
+
break;
|
|
157
113
|
|
|
158
|
-
|
|
114
|
+
case "l": // lineTo
|
|
115
|
+
x = outline[i++] * scale + offsetX;
|
|
116
|
+
y = outline[i++] * scale + offsetY;
|
|
159
117
|
|
|
160
|
-
|
|
118
|
+
path.lineTo(x, y);
|
|
161
119
|
|
|
162
|
-
|
|
163
|
-
cpy = outline[ i ++ ] * scale + offsetY;
|
|
164
|
-
cpx1 = outline[ i ++ ] * scale + offsetX;
|
|
165
|
-
cpy1 = outline[ i ++ ] * scale + offsetY;
|
|
166
|
-
cpx2 = outline[ i ++ ] * scale + offsetX;
|
|
167
|
-
cpy2 = outline[ i ++ ] * scale + offsetY;
|
|
120
|
+
break;
|
|
168
121
|
|
|
169
|
-
|
|
122
|
+
case "q": // quadraticCurveTo
|
|
123
|
+
cpx = outline[i++] * scale + offsetX;
|
|
124
|
+
cpy = outline[i++] * scale + offsetY;
|
|
125
|
+
cpx1 = outline[i++] * scale + offsetX;
|
|
126
|
+
cpy1 = outline[i++] * scale + offsetY;
|
|
170
127
|
|
|
171
|
-
|
|
128
|
+
path.quadraticCurveTo(cpx1, cpy1, cpx, cpy);
|
|
172
129
|
|
|
173
|
-
|
|
130
|
+
break;
|
|
174
131
|
|
|
175
|
-
|
|
132
|
+
case "b": // bezierCurveTo
|
|
133
|
+
cpx = outline[i++] * scale + offsetX;
|
|
134
|
+
cpy = outline[i++] * scale + offsetY;
|
|
135
|
+
cpx1 = outline[i++] * scale + offsetX;
|
|
136
|
+
cpy1 = outline[i++] * scale + offsetY;
|
|
137
|
+
cpx2 = outline[i++] * scale + offsetX;
|
|
138
|
+
cpy2 = outline[i++] * scale + offsetY;
|
|
176
139
|
|
|
177
|
-
|
|
140
|
+
path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, cpx, cpy);
|
|
178
141
|
|
|
179
|
-
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
180
146
|
|
|
147
|
+
return { offsetX: glyph.ha * scale, path: path };
|
|
181
148
|
}
|
|
182
149
|
|
|
183
150
|
export { FontLoader, Font };
|
package/src/grid.js
CHANGED
|
@@ -1,37 +1,90 @@
|
|
|
1
1
|
import * as THREE from "three";
|
|
2
|
+
import { Font } from "./fontloader/FontLoader.js";
|
|
3
|
+
import { helvetiker } from "./font.js";
|
|
2
4
|
|
|
3
5
|
class Grid {
|
|
4
|
-
constructor(display, bbox, ticks, axes0, grid, flipY) {
|
|
6
|
+
constructor(display, bbox, ticks, centerGrid, axes0, grid, flipY, theme) {
|
|
5
7
|
if (ticks === undefined) {
|
|
6
8
|
ticks = 10;
|
|
7
9
|
}
|
|
8
10
|
this.display = display;
|
|
9
11
|
this.bbox = bbox;
|
|
10
|
-
|
|
12
|
+
this.centerGrid = centerGrid;
|
|
11
13
|
this.grid = grid;
|
|
12
14
|
this.allGrid = grid[0] | grid[1] | grid[2];
|
|
15
|
+
const s = new THREE.Vector3();
|
|
16
|
+
bbox.getSize(s);
|
|
17
|
+
const s2 = Math.max(s.x, s.y, s.z);
|
|
18
|
+
// const s2 = bbox.boundingSphere().radius;
|
|
13
19
|
|
|
14
20
|
this.gridHelper = [];
|
|
15
21
|
// in case the bbox has the same siez as the nice grid there should be
|
|
16
22
|
// a margin bewteen grid and object. Hence factor 1.1
|
|
17
23
|
var [axisStart, axisEnd, niceTick] = this.niceBounds(
|
|
18
|
-
-
|
|
19
|
-
|
|
24
|
+
-s2 * 1.05,
|
|
25
|
+
s2 * 1.05,
|
|
20
26
|
2 * ticks,
|
|
21
27
|
);
|
|
22
28
|
this.size = axisEnd - axisStart;
|
|
23
29
|
|
|
30
|
+
const font = new Font(helvetiker);
|
|
31
|
+
|
|
24
32
|
this.ticks = niceTick;
|
|
25
33
|
|
|
26
34
|
for (var i = 0; i < 3; i++) {
|
|
27
|
-
|
|
35
|
+
var group = new THREE.Group();
|
|
36
|
+
group.name = `GridHelper-${i}`;
|
|
37
|
+
group.add(
|
|
28
38
|
new THREE.GridHelper(
|
|
29
39
|
this.size,
|
|
30
40
|
this.size / this.ticks,
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
theme === "dark" ? 0xcccccc : 0x777777,
|
|
42
|
+
theme == "dark" ? 0x999999 : 0xbbbbbb,
|
|
33
43
|
),
|
|
34
44
|
);
|
|
45
|
+
const mat = new THREE.LineBasicMaterial({
|
|
46
|
+
color:
|
|
47
|
+
theme === "dark"
|
|
48
|
+
? new THREE.Color(0.5, 0.5, 0.5)
|
|
49
|
+
: new THREE.Color(0.4, 0.4, 0.4),
|
|
50
|
+
side: THREE.DoubleSide,
|
|
51
|
+
});
|
|
52
|
+
var dir;
|
|
53
|
+
var geom;
|
|
54
|
+
for (var x = -this.size / 2; x <= this.size / 2; x += this.ticks) {
|
|
55
|
+
geom = this.createNumber(x, font);
|
|
56
|
+
if (i == 0) {
|
|
57
|
+
geom.rotateX(-Math.PI / 2);
|
|
58
|
+
geom.rotateY(Math.PI / 2);
|
|
59
|
+
} else if (i == 1) {
|
|
60
|
+
geom.rotateX(Math.PI / 2);
|
|
61
|
+
geom.rotateY(-Math.PI / 2);
|
|
62
|
+
} else {
|
|
63
|
+
geom.rotateX(Math.PI / 2);
|
|
64
|
+
geom.rotateY(-Math.PI / 2);
|
|
65
|
+
}
|
|
66
|
+
const label = new THREE.Mesh(geom, mat);
|
|
67
|
+
dir = i == 1 ? -1 : 1;
|
|
68
|
+
label.position.set(dir * x, 0, 0);
|
|
69
|
+
group.add(label);
|
|
70
|
+
|
|
71
|
+
if (Math.abs(x) < 1e-6) continue;
|
|
72
|
+
|
|
73
|
+
geom = this.createNumber(x, font);
|
|
74
|
+
if (i == 0) {
|
|
75
|
+
geom.rotateX(-Math.PI / 2);
|
|
76
|
+
} else if (i == 1) {
|
|
77
|
+
geom.rotateX(-Math.PI / 2);
|
|
78
|
+
geom.rotateZ(Math.PI);
|
|
79
|
+
} else {
|
|
80
|
+
geom.rotateX(Math.PI / 2);
|
|
81
|
+
}
|
|
82
|
+
const label2 = new THREE.Mesh(geom, mat);
|
|
83
|
+
dir = i == 0 ? -1 : 1;
|
|
84
|
+
label2.position.set(0, 0, dir * x);
|
|
85
|
+
group.add(label2);
|
|
86
|
+
}
|
|
87
|
+
this.gridHelper.push(group);
|
|
35
88
|
}
|
|
36
89
|
|
|
37
90
|
this.gridHelper[0].rotateX(Math.PI / 2);
|
|
@@ -43,6 +96,21 @@ class Grid {
|
|
|
43
96
|
this.setVisible();
|
|
44
97
|
}
|
|
45
98
|
|
|
99
|
+
createNumber(x, font) {
|
|
100
|
+
// experimentally detected: p1=(size=640, font_size=7.1) p2=(size=2.2, font_size=0.035)
|
|
101
|
+
const m = (0.035 - 7.1) / (2.2 - 640);
|
|
102
|
+
const fontSize = m * (this.size - 640) + 7.1;
|
|
103
|
+
|
|
104
|
+
const shape = font.generateShapes(x.toFixed(1), fontSize);
|
|
105
|
+
var geom = new THREE.ShapeGeometry(shape);
|
|
106
|
+
|
|
107
|
+
geom.computeBoundingBox();
|
|
108
|
+
var xMid = -0.5 * (geom.boundingBox.max.x - geom.boundingBox.min.x);
|
|
109
|
+
var yMid = -0.5 * (geom.boundingBox.max.y - geom.boundingBox.min.y);
|
|
110
|
+
geom.translate(xMid, yMid, 0);
|
|
111
|
+
return geom;
|
|
112
|
+
}
|
|
113
|
+
|
|
46
114
|
// https://stackoverflow.com/questions/4947682/intelligently-calculating-chart-tick-positions
|
|
47
115
|
niceNumber(value, round) {
|
|
48
116
|
var exponent = Math.floor(Math.log10(value));
|
|
@@ -109,7 +177,7 @@ class Grid {
|
|
|
109
177
|
setGrid(action, flag = null) {
|
|
110
178
|
switch (action) {
|
|
111
179
|
case "grid":
|
|
112
|
-
this.allGrid =
|
|
180
|
+
this.allGrid = flag == null ? !this.allGrid : flag;
|
|
113
181
|
this.grid[0] = this.allGrid;
|
|
114
182
|
this.grid[1] = this.allGrid;
|
|
115
183
|
this.grid[2] = this.allGrid;
|
|
@@ -139,17 +207,25 @@ class Grid {
|
|
|
139
207
|
for (var i = 0; i < 3; i++) {
|
|
140
208
|
this.gridHelper[i].position.set(0, 0, 0);
|
|
141
209
|
}
|
|
142
|
-
this.gridHelper[0].position.z = -this.size / 2;
|
|
143
|
-
this.gridHelper[1].position.y =
|
|
144
|
-
|
|
210
|
+
this.gridHelper[0].position.z = this.centerGrid ? 0 : -this.size / 2;
|
|
211
|
+
this.gridHelper[1].position.y = this.centerGrid
|
|
212
|
+
? 0
|
|
213
|
+
: ((flipY ? 1 : -1) * this.size) / 2;
|
|
214
|
+
this.gridHelper[2].position.x = this.centerGrid ? 0 : -this.size / 2;
|
|
145
215
|
} else {
|
|
146
216
|
const c = this.bbox.center();
|
|
147
217
|
for (i = 0; i < 3; i++) {
|
|
148
218
|
this.gridHelper[i].position.set(...c);
|
|
149
219
|
}
|
|
150
|
-
this.gridHelper[0].position.z =
|
|
151
|
-
|
|
152
|
-
|
|
220
|
+
this.gridHelper[0].position.z = this.centerGrid
|
|
221
|
+
? c[2]
|
|
222
|
+
: -this.size / 2 + c[2];
|
|
223
|
+
this.gridHelper[1].position.y = this.centerGrid
|
|
224
|
+
? c[1]
|
|
225
|
+
: ((flipY ? 1 : -1) * this.size) / 2 + c[1];
|
|
226
|
+
this.gridHelper[2].position.x = this.centerGrid
|
|
227
|
+
? c[0]
|
|
228
|
+
: -this.size / 2 + c[0];
|
|
153
229
|
}
|
|
154
230
|
}
|
|
155
231
|
|
package/src/icons.js
CHANGED
|
@@ -45,7 +45,6 @@ import dark_shape_no from "../icons/dark/shape_no.svg";
|
|
|
45
45
|
import dark_stop from "../icons/dark/stop.svg";
|
|
46
46
|
import dark_top from "../icons/dark/top.svg";
|
|
47
47
|
|
|
48
|
-
|
|
49
48
|
import dark_axes from "../icons/dark/axes.svg";
|
|
50
49
|
import dark_axes0 from "../icons/dark/axes0.svg";
|
|
51
50
|
import dark_grid from "../icons/dark/grid.svg";
|
|
@@ -68,7 +67,6 @@ import light_angle from "../icons/light/angle.svg";
|
|
|
68
67
|
import light_transparent from "../icons/light/transparent.svg";
|
|
69
68
|
import light_blackedges from "../icons/light/black_edges.svg";
|
|
70
69
|
|
|
71
|
-
|
|
72
70
|
const icons = {
|
|
73
71
|
bottom: { light: light_bottom, dark: dark_bottom },
|
|
74
72
|
front: { light: light_front, dark: dark_front },
|
package/src/index.html
CHANGED
|
@@ -122,18 +122,29 @@
|
|
|
122
122
|
</div>
|
|
123
123
|
</div>
|
|
124
124
|
<div class="tcv_clip_checks">
|
|
125
|
-
<
|
|
126
|
-
<span class="
|
|
127
|
-
class='tcv_clip_intersection tcv_check' type="checkbox" />
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<span class="
|
|
131
|
-
class='tcv_clip_plane_helpers tcv_axes0 tcv_check' type="checkbox" />
|
|
125
|
+
<div>
|
|
126
|
+
<span class="tcv_tooltip" data-tooltip="Use intersection clipping">
|
|
127
|
+
<input class='tcv_clip_intersection tcv_check' type="checkbox" />
|
|
128
|
+
<span class="tcv_label">Intersection</span>
|
|
129
|
+
</span>
|
|
130
|
+
<span class="tcv_tooltip" data-tooltip="Show clipping planes">
|
|
131
|
+
<input class='tcv_clip_plane_helpers tcv_axes0 tcv_check' type="checkbox" />
|
|
132
|
+
<span class="tcv_label">Planes</span>
|
|
133
|
+
</span>
|
|
134
|
+
</div>
|
|
135
|
+
<span class="tcv_tooltip" data-tooltip="Use object color caps instead of RGB">
|
|
136
|
+
<input class='tcv_clip_caps tcv_axes0 tcv_check' type="checkbox" />
|
|
137
|
+
<span class="tcv_label">Use object color caps</span>
|
|
132
138
|
</span>
|
|
133
139
|
</div>
|
|
134
140
|
</div>
|
|
135
141
|
<div class="tcv_cad_material_container">
|
|
136
|
-
<div class="
|
|
142
|
+
<div class="tcv_cad_tree_toggles">
|
|
143
|
+
<span class="tcv_tooltip" data-tooltip="Reset to original values">
|
|
144
|
+
<input class='tcv_material_reset tcv_btn tcv_small_btn' value="R" type="button" />
|
|
145
|
+
</span>
|
|
146
|
+
</div>
|
|
147
|
+
<div class="tcv_material_ambientlight tcv_label">
|
|
137
148
|
Ambient light intensity (%)
|
|
138
149
|
</div>
|
|
139
150
|
<div class="tcv_slider_group">
|