Skip to content

Commit 72172cf

Browse files
authored
Add files via upload
1 parent 138ed1a commit 72172cf

File tree

2 files changed

+283
-0
lines changed

2 files changed

+283
-0
lines changed

TrunkMeshVolume/TreeMeshing.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/// <reference path="C:\Program Files\Leica Geosystems\Cyclone 3DR 19.1\Script\JsDoc\Reshaper.d.ts"/>
2+
3+
// ------------------------ HOW TO USE IT --------------------------------------------
4+
// The algorithm uses the selected cloud to mesh it using this tree meshing strategy! => Make sure only 1 cloud is selected before launching the script
5+
//
6+
// ------------------------ ALGORITHM USED --------------------------------------------
7+
// 1. The algorithm creates slices of defined depth in the point cloud at regular steps in Z
8+
// 2. A section of each slice is created using the convex hull algorithm
9+
// 3. The sections are joined in order to create a watertight mesh
10+
//
11+
// ------------------------ PARAMETERS --------------------------------------------
12+
// Parameter explanations:
13+
// 1. Slice step: distance between the sections that have to be created
14+
// 2. Slice depth: depth of each section for creating the convex hull
15+
//
16+
17+
18+
function ErrorMessage(_iMessage // [in] the error message
19+
, _iThrowError = true // [in] should we throw an error (default value: true)
20+
) {
21+
var _iThrowError = (typeof _iThrowError !== 'undefined') ? _iThrowError : true;
22+
23+
var myDlg = SDialog.New("Error Message");
24+
myDlg.AddLine(_iMessage, false, {}, 1);
25+
myDlg.Execute();
26+
if (_iThrowError)
27+
throw new Error(_iMessage);
28+
}
29+
30+
31+
function mainTreeMeshing() {
32+
// retrieving the cloud to mesh with this approach
33+
var selClouds = SCloud.FromSel();
34+
if (selClouds.length != 1)
35+
ErrorMessage("This script needs 1 cloud to be selected")
36+
var theCloud = selClouds[0];
37+
38+
//Enter the input data
39+
var theDialog = SDialog.New('Tree meshing parameters');
40+
theDialog.AddLine("Slice step: ", true, {}, 1);
41+
theDialog.AddLine("Slice depth: ", true, {}, 0.5);
42+
43+
var result = theDialog.Execute();
44+
if (result.ErrorCode != 0)// result == 0 means the user click on the "OK" button
45+
ErrorMessage("Operation canceled");
46+
47+
var Param_Slice_Step = parseFloat(result.InputTbl[0]);
48+
var Param_Slice_Depth = parseFloat(result.InputTbl[1]);
49+
50+
// looking for the different heights at which we will create the mesh
51+
var ZVect = SVector.New(0, 0, 1);
52+
var centroid = theCloud.GetCentroid().Point;
53+
var LPt = theCloud.GetLowestPoint(ZVect).Point.GetZ();
54+
var UPt = theCloud.GetHighestPoint(SVector.New(0, 0, 1)).Point.GetZ();
55+
if (UPt - LPt < 2 * Param_Slice_Step)
56+
ErrorMessage("Too few steps will be created to mesh")
57+
58+
var NStep = Math.round((UPt - LPt) / Param_Slice_Step);
59+
60+
// looping on each height to create the convex contours
61+
var allMultis = new Array;
62+
for (var iHeight = 0; iHeight < NStep; iHeight++) {
63+
var curZ = LPt + iHeight * Param_Slice_Step;
64+
var locPoint = SPoint.New(centroid.GetX(), centroid.GetY(), curZ);
65+
var curPlane = SPlane.New(locPoint, ZVect, SVector.New(1, 0, 0), 1, 1);
66+
67+
var localCloud = theCloud.SeparateFeature(curPlane, Param_Slice_Depth, SCloud.FILL_IN_ONLY).InCloud;
68+
69+
var convContRes = localCloud.GetConvexContour(ZVect, locPoint, false);
70+
if (convContRes.ErrorCode != 0)
71+
ErrorMessage("Error when extracting convex contours")
72+
73+
allMultis.push(convContRes.Multi)
74+
}
75+
76+
// creating the meshes at each heights
77+
78+
var allPolys = new Array;
79+
// adding bottom
80+
var bottomRes = SPoly.ConstraintMesh2D(null, [allMultis[0]], ZVect, 0, 0);
81+
if (bottomRes.ErrorCode != 0 || bottomRes.PolyTbl.length != 1)
82+
ErrorMessage("Error when creating bottom")
83+
allPolys.push(bottomRes.PolyTbl[0])
84+
85+
// looping on each height
86+
for (var iHeight = 0; iHeight < NStep - 1; iHeight++) {
87+
var locLMultis = new Array;
88+
locLMultis.push(allMultis[iHeight])
89+
locLMultis.push(allMultis[iHeight + 1])
90+
var meshRes = SPoly.JoinContour(locLMultis, [], 0, 0, 0, false, 0);
91+
if (meshRes.ErrorCode != 0)
92+
ErrorMessage("Error when joining contours")
93+
allPolys.push(meshRes.Poly)
94+
}
95+
96+
// adding top
97+
var topRes = SPoly.ConstraintMesh2D(null, [allMultis[allMultis.length - 1]], ZVect, 0, 0);
98+
if (topRes.ErrorCode != 0 || topRes.PolyTbl.length != 1)
99+
ErrorMessage("Error when creating top")
100+
allPolys.push(topRes.PolyTbl[0])
101+
102+
// merging the results (final should be only 1 filled mesh)
103+
var resMerge = SPoly.MergeCommonBorders(allPolys, SPoly.SIMPLE);
104+
if (resMerge.ErrorCode != 0)
105+
ErrorMessage("Error when mergin meshes")
106+
107+
var finalMeshes = resMerge.PolyTbl;
108+
for (var iMesh = 0; iMesh < finalMeshes.length; iMesh++) {
109+
finalMeshes[iMesh].SetName(theCloud.GetName())
110+
finalMeshes[iMesh].AddToDoc();
111+
}
112+
113+
}
114+
115+
mainTreeMeshing()

TrunkMeshVolume/TrunkMeshing.js

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/// <reference path="C:\Program Files\Leica Geosystems\Cyclone 3DR 19.1\Script\JsDoc\Reshaper.d.ts"/>
2+
3+
// ------------------------ HOW TO USE IT --------------------------------------------
4+
// This algoritm is a modification of the TreeMeshing.js. The algorithm uses the selected clouds to mesh them using this trunk meshing strategy! => Make sure to select the clouds firts
5+
//
6+
// ------------------------ ALGORITHM USED --------------------------------------------
7+
// 1. The algorithm creates slices of defined depth in the point cloud at regular steps in Z
8+
// 2. A section of each slice is created using the convex hull algorithm
9+
// 3. The sections are joined in order to create a watertight mesh
10+
// 4. MODIFICATION - it also calculates the total volume
11+
//
12+
// ------------------------ PARAMETERS --------------------------------------------
13+
// Parameter explanations:
14+
// 1. Slice step: distance between the sections that have to be created
15+
// 2. Slice depth: depth of each section for creating the convex hull
16+
//
17+
18+
19+
function ErrorMessage(_iMessage // [in] the error message
20+
, _iThrowError = true // [in] should we throw an error (default value: true)
21+
) {
22+
var _iThrowError = (typeof _iThrowError !== 'undefined') ? _iThrowError : true;
23+
24+
var myDlg = SDialog.New("Error Message");
25+
myDlg.AddLine(_iMessage, false, {}, 1);
26+
myDlg.Execute();
27+
if (_iThrowError)
28+
throw new Error(_iMessage);
29+
}
30+
31+
32+
function mainTreeMeshing() {
33+
// Total Volume
34+
var VolumeTotal = 0
35+
// retrieving the cloud to mesh with this approach
36+
var selClouds = SCloud.FromSel();
37+
if (selClouds.length == 0)
38+
ErrorMessage("Esqueceu de selecionar as nuvens de pontos!")
39+
for (let i = 0; i<selClouds.length; i++) {
40+
var theCloud = selClouds[i];
41+
42+
43+
44+
//Enter the input data
45+
//var theDialog = SDialog.New('Tree meshing parameters');
46+
//theDialog.AddLine("Slice step: ", true, {}, 1);
47+
//theDialog.AddLine("Slice depth: ", true, {}, 0.5);
48+
49+
//var result = theDialog.Execute();
50+
//if (result.ErrorCode != 0)// result == 0 means the user click //on the "OK" button
51+
//ErrorMessage("Operation canceled");
52+
53+
var Param_Slice_Step = 1 //parseFloat(result.InputTbl[0]);
54+
var Param_Slice_Depth = 0.5 //parseFloat(result.InputTbl[1]);
55+
56+
// looking for the different heights at which we will create the mesh
57+
var ZVect = SVector.New(0, 0, 1);
58+
var centroid = theCloud.GetCentroid().Point;
59+
var LPt = theCloud.GetLowestPoint(ZVect).Point.GetZ();
60+
var UPt = theCloud.GetHighestPoint(SVector.New(0, 0, 1)).Point.GetZ();
61+
try{
62+
if (UPt - LPt < 2 * Param_Slice_Step)
63+
console.error('Too few steps will be created to mesh')
64+
//ErrorMessage("Too few steps will be created to mesh")
65+
} catch (error) {
66+
//console.error('An error occurred:', error);
67+
continue;
68+
}
69+
70+
var NStep = Math.round((UPt - LPt) / Param_Slice_Step);
71+
72+
// looping on each height to create the convex contours
73+
var allMultis = new Array;
74+
for (var iHeight = 0; iHeight < NStep; iHeight++) {
75+
var curZ = LPt + iHeight * Param_Slice_Step;
76+
var locPoint = SPoint.New(centroid.GetX(), centroid.GetY(), curZ);
77+
var curPlane = SPlane.New(locPoint, ZVect, SVector.New(1, 0, 0), 1, 1);
78+
79+
var localCloud = theCloud.SeparateFeature(curPlane, Param_Slice_Depth, SCloud.FILL_IN_ONLY).InCloud;
80+
81+
try{
82+
var convContRes = localCloud.GetConvexContour(ZVect, locPoint, false);
83+
84+
if (convContRes.ErrorCode != 0)
85+
console.error("Error when extracting convex contours")
86+
} catch (error) {
87+
continue;
88+
//ErrorMessage("Error when extracting convex contours")
89+
}
90+
allMultis.push(convContRes.Multi)
91+
}
92+
93+
// creating the meshes at each heights
94+
95+
var allPolys = new Array;
96+
// adding bottom
97+
try{
98+
var bottomRes = SPoly.ConstraintMesh2D(null, [allMultis[0]], ZVect, 0, 0);
99+
100+
if (bottomRes.ErrorCode != 0 || bottomRes.PolyTbl.length != 1)
101+
console.error('Error when creating bottom')
102+
//ErrorMessage("Too few steps will be created to mesh")
103+
} catch (error) {
104+
//console.error('An error occurred:', error);
105+
continue;
106+
}
107+
//ErrorMessage("Error when creating bottom")
108+
allPolys.push(bottomRes.PolyTbl[0])
109+
110+
// looping on each height
111+
for (var iHeight = 0; iHeight < NStep - 1; iHeight++) {
112+
var locLMultis = new Array;
113+
locLMultis.push(allMultis[iHeight])
114+
locLMultis.push(allMultis[iHeight + 1])
115+
116+
try {
117+
118+
var meshRes = SPoly.JoinContour(locLMultis, [], 0, 0, 0, false, 0);
119+
120+
if (meshRes.ErrorCode != 0)
121+
console.error("Error when joining contours")
122+
} catch (error) {
123+
continue;
124+
//ErrorMessage("Error when joining contours")
125+
}
126+
allPolys.push(meshRes.Poly)
127+
}
128+
129+
// adding top
130+
try {
131+
132+
var topRes = SPoly.ConstraintMesh2D(null, [allMultis[allMultis.length - 1]], ZVect, 0, 0);
133+
134+
if (topRes.ErrorCode != 0 || topRes.PolyTbl.length != 1)
135+
console.error("Error when creating top")
136+
} catch (error) {
137+
//ErrorMessage("Error when creating top")
138+
continue;
139+
}
140+
allPolys.push(topRes.PolyTbl[0])
141+
142+
// merging the results (final should be only 1 filled mesh)
143+
try {
144+
145+
var resMerge = SPoly.MergeCommonBorders(allPolys, SPoly.SIMPLE);
146+
147+
if (resMerge.ErrorCode != 0)
148+
console.error("Error when mergin meshes")
149+
} catch (error) {
150+
continue;
151+
//ErrorMessage("Error when mergin meshes")
152+
}
153+
154+
var finalMeshes = resMerge.PolyTbl;
155+
for (var iMesh = 0; iMesh < finalMeshes.length; iMesh++) {
156+
finalMeshes[iMesh].SetName(theCloud.GetName())
157+
finalMeshes[iMesh].AddToDoc();
158+
}
159+
//print())
160+
VolumeTotal = VolumeTotal + finalMeshes[0].GetVolume().Volume;
161+
162+
console.log("Done", i)
163+
164+
}
165+
print((`O Volume Total é: ${VolumeTotal} unidades de volume`))
166+
}
167+
168+
mainTreeMeshing()

0 commit comments

Comments
 (0)