Skip to content

Commit 1da2c41

Browse files
committed
new adjust-edge-length-extended is optionally available.
1 parent 14ad7cc commit 1da2c41

File tree

4 files changed

+219
-55
lines changed

4 files changed

+219
-55
lines changed

gradle/project-info.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// -----------------------------------------------------------------------------
44
ext.publishing.artifactId = project.name.toLowerCase()
55
ext.publishing.groupId = 'eu.mihosoft.jcsg.ext.mesh'
6-
ext.publishing.versionId = '0.4.1'
6+
ext.publishing.versionId = '0.4.2'
77

88
ext.publishing.developerName = 'Michael Hoffer'
99
ext.publishing.developerAlias = 'miho'

src/main/java/eu/mihosoft/jcsg/ext/mesh/MeshTools.java

Lines changed: 113 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -93,49 +93,15 @@ public static CSG optimize(
9393
double maxEdgeLength,
9494
int maxIter,
9595
double creaseEdgeAngle) {
96-
try {
97-
98-
Path tmpDir = Files.createTempDirectory("jcsgmeshopt");
99-
Path stlFile = Paths.get(tmpDir.toAbsolutePath().toString(),
100-
"csg.stl");
101-
102-
System.out.println("mesh-ext: csg file: " + stlFile);
103-
104-
Files.write(stlFile, csg.toStlString().getBytes());
105-
106-
String code = read("optimize-and-repair.lua");
107-
108-
String pathVariable = stlFile.toAbsolutePath().toString();//
109-
110-
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
111-
pathVariable = pathVariable.replace("\\", "\\\\");
112-
}
113-
114-
code = code.replace("$filename$", "\""
115-
+ pathVariable + "\"");
116-
code = code.replace("$removeDoublesTOL$", "" + tol);
117-
code = code.replace("$creaseEdgeAngle$", "" + creaseEdgeAngle);
118-
code = code.replace("$resolveTOL$", "" + maxTol);
119-
code = code.replace("$minEdgeLength$", "" + minEdgeLength);
120-
code = code.replace("$maxEdgeLength$", "" + maxEdgeLength);
121-
code = code.replace("$maxAdjIter$", "" + maxIter);
122-
123-
// code = code.replace("$edgeApprox$", "" + edgeApprox);
124-
// code = code.replace("$edgeTriangleQuality$", "" + edgeTriangleQuality);
125-
Shell.execute(tmpDir.toFile(), code).print().waitFor();
126-
127-
return STL.file(stlFile);
128-
129-
} catch (IOException e) {
130-
e.printStackTrace(System.err);
131-
throw new RuntimeException(
132-
"optimization failed due to io exception", e);
133-
}
96+
return optimize(
97+
"adjust-edge-length",
98+
csg, tol, maxTol, minEdgeLength, maxEdgeLength,
99+
-1, -1, maxIter, creaseEdgeAngle);
134100
}
135101

136102
/**
137103
* Optimizes and repairs the specified csg mesh object.
138-
*
104+
*
139105
* <b>Note: </b>the size of the
140106
* object during optimization can have a high impact on the overall
141107
* optimization quality. Therefore, this method allows the specification of
@@ -164,8 +130,8 @@ public static CSG optimize(
164130
}
165131

166132
/**
167-
* Optimizes and repairs the specified csg mesh object.
168-
*
133+
* Optimizes and repairs the specified csg mesh object.
134+
*
169135
* <b>Note: </b>the size of the
170136
* object during optimization can have a high impact on the overall
171137
* optimization quality. Therefore, this method allows the specification of
@@ -184,18 +150,119 @@ public static CSG optimize(
184150
* @return optimized csg mesh object
185151
*/
186152
public static CSG optimize(CSG csg,
187-
double size,
188-
double tol,
153+
double size,
154+
double tol,
155+
double maxTol,
156+
double minEdgeLength,
157+
double maxEdgeLength,
158+
int maxIter,
159+
double creaseEdgeAngle) {
160+
return scaleMinDimensionTo(csg, size,
161+
(csgObj) -> optimize(csgObj, tol, maxTol,
162+
minEdgeLength, maxEdgeLength));
163+
}
164+
165+
/**
166+
* Optimizes and repairs the specified csg mesh object.
167+
*
168+
* <b>Note: </b>the size of the
169+
* object during optimization can have a high impact on the overall
170+
* optimization quality. Therefore, this method allows the specification of
171+
* the size at which the optimization is performed. After the optimization
172+
* the object is returned at original size.
173+
*
174+
* @param csg csg to optimize
175+
* @param size object size at which to perform the optimization (minimum
176+
* dimension)
177+
* @param tol default tolerance
178+
* @param maxTol maximum tolerance
179+
* @param minEdgeLength minimum edge length
180+
* @param maxEdgeLength maximum edge length
181+
* @param maxIter number of iterations for edge length adjustment
182+
* @param creaseEdgeAngle angle threashold for crease edge marker
183+
* @return optimized csg mesh object
184+
*/
185+
public static CSG optimize(CSG csg, double size, double tol,
186+
double maxTol,
187+
double minEdgeLength,
188+
double maxEdgeLength,
189+
double edgeApprox,
190+
double edgeTriangleQuality,
191+
int maxIter,
192+
double creaseEdgeAngle) {
193+
return scaleMinDimensionTo(csg, size,
194+
(csgObj) -> optimize("adjust-edge-length-extended", csgObj, tol, maxTol,
195+
minEdgeLength, maxEdgeLength,edgeApprox,edgeTriangleQuality,maxIter,creaseEdgeAngle));
196+
}
197+
198+
/**
199+
* Optimizes and repairs the specified csg mesh object.
200+
*
201+
* @param csg csg to optimize
202+
* @param tol default tolerance
203+
* @param maxTol maximum tolerance
204+
* @param minEdgeLength minimum edge length
205+
* @param maxEdgeLength maximum edge length
206+
* @param maxIter number of iterations for edge length adjustment
207+
* @param creaseEdgeAngle angle threashold for crease edge marker
208+
* @return optimized csg mesh object
209+
*/
210+
private static CSG optimize(
211+
String optType,
212+
CSG csg, double tol,
189213
double maxTol,
190214
double minEdgeLength,
191215
double maxEdgeLength,
216+
double edgeApprox,
217+
double edgeTriangleQuality,
192218
int maxIter,
193219
double creaseEdgeAngle) {
194-
return scaleMinDimensionTo(csg, size,
195-
(csgObj) -> optimize(csgObj, tol, maxTol,
196-
minEdgeLength, maxEdgeLength));
220+
try {
221+
222+
Path tmpDir = Files.createTempDirectory("jcsgmeshopt");
223+
Path stlFile = Paths.get(tmpDir.toAbsolutePath().toString(),
224+
"csg.stl");
225+
226+
System.out.println("mesh-ext: csg file: " + stlFile);
227+
228+
Files.write(stlFile, csg.toStlString().getBytes());
229+
230+
String code = read("optimize-and-repair.lua");
231+
232+
String pathVariable = stlFile.toAbsolutePath().toString();//
233+
234+
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
235+
pathVariable = pathVariable.replace("\\", "\\\\");
236+
}
237+
238+
code = code.replace("$optType$", "\""
239+
+ optType + "\"");
240+
code = code.replace("$fileName$", "\""
241+
+ pathVariable + "\"");
242+
code = code.replace("$removeDoublesTOL$", "" + tol);
243+
code = code.replace("$creaseEdgeAngle$", "" + creaseEdgeAngle);
244+
code = code.replace("$resolveTOL$", "" + maxTol);
245+
code = code.replace("$minEdgeLength$", "" + minEdgeLength);
246+
code = code.replace("$maxEdgeLength$", "" + maxEdgeLength);
247+
code = code.replace("$maxAdjIter$", "" + maxIter);
248+
249+
code = code.replace("$edgeApprox$", "" + edgeApprox);
250+
code = code.replace("$edgeTriangleQuality$", "" + edgeTriangleQuality);
251+
252+
// code = code.replace("$edgeApprox$", "" + edgeApprox);
253+
// code = code.replace("$edgeTriangleQuality$", "" + edgeTriangleQuality);
254+
Shell.execute(tmpDir.toFile(), code).print().waitFor();
255+
256+
return STL.file(stlFile);
257+
258+
} catch (IOException e) {
259+
e.printStackTrace(System.err);
260+
throw new RuntimeException(
261+
"optimization failed due to io exception", e);
262+
}
197263
}
198264

265+
199266
/**
200267
* Scales the minimum CSG dimension to the specified value, invokes the
201268
* specified function and rescales the specified CSG object to its original

src/main/resources/eu/mihosoft/jcsg/ext/mesh/optimize-and-repair.lua

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--
22
-- optimize.lua
33
--
4-
-- Copyright 2016 Michael Hoffer <[email protected]>. All rights reserved.
4+
-- Copyright 2016-2017 Michael Hoffer <[email protected]>. All rights reserved.
55
--
66
-- Redistribution and use in source and binary forms, with or without modification, are
77
-- permitted provided that the following conditions are met:
@@ -33,18 +33,20 @@
3333
--
3434

3535
-- script parameters
36-
fileName = $filename$
36+
fileName = $fileName$
3737
removeDoublesTOL = $removeDoublesTOL$
3838
creaseEdgeAngle = $creaseEdgeAngle$
3939
resolveTOL = $resolveTOL$
4040
minEdgeLength = $minEdgeLength$
4141
maxEdgeLength = $maxEdgeLength$
4242
maxAdjIter = $maxAdjIter$
4343

44-
-- might be useful if we use new adjustEdgeLengthExtended
45-
-- (currently, not stable enough, might be just a parameter problem)
46-
--edgeApprox = $edgeApprox$
47-
--edgeTriangleQuality = $edgeTriangleQuality$
44+
-- selects optimization type
45+
optType = $optType$
46+
47+
-- necessary if we use new adjustEdgeLengthExtended
48+
edgeApprox = $edgeApprox$
49+
edgeTriangleQuality = $edgeTriangleQuality$
4850

4951
-- check whether boundery edges exist
5052
function hasBoundaryEdges(meshP)
@@ -102,8 +104,14 @@ SelectCreaseEdges(mesh,creaseEdgeAngle)
102104
MarkSelection(mesh)
103105

104106
print("> retriangulate")
105-
AdjustEdgeLength(mesh, minEdgeLength, maxEdgeLength, maxAdjIter, true, true)
106-
--AdjustEdgeLengthExtended(mesh, minEdgeLength, maxEdgeLength, edgeApprox, edgeTriangleQuality, maxAdjIter, true)
107+
if optType=="adjust-edge-length" then
108+
AdjustEdgeLength(mesh, minEdgeLength, maxEdgeLength, maxAdjIter, true, true)
109+
elseif optType=="adjust-edge-length-extended" then
110+
AdjustEdgeLengthExtended(mesh, minEdgeLength, maxEdgeLength, edgeApprox, edgeTriangleQuality, maxAdjIter, true)
111+
else
112+
print(" -> ERROR: optimization type '"..optType.."' not supported.")
113+
do return 1 end -- quit with exit code
114+
end
107115

108116
ClearMarks(mesh)
109117

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
--
2+
-- optimize.lua
3+
--
4+
-- Copyright 2016-2017 Michael Hoffer <[email protected]>. All rights reserved.
5+
--
6+
-- Redistribution and use in source and binary forms, with or without modification, are
7+
-- permitted provided that the following conditions are met:
8+
--
9+
-- 1. Redistributions of source code must retain the above copyright notice, this list of
10+
-- conditions and the following disclaimer.
11+
--
12+
-- 2. Redistributions in binary form must reproduce the above copyright notice, this list
13+
-- of conditions and the following disclaimer in the documentation and/or other materials
14+
-- provided with the distribution.
15+
--
16+
-- THIS SOFTWARE IS PROVIDED BY Michael Hoffer <[email protected]> "AS IS" AND ANY EXPRESS OR IMPLIED
17+
-- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18+
-- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer <[email protected]> OR
19+
-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20+
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21+
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22+
-- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23+
-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24+
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
--
26+
-- The views and conclusions contained in the software and documentation are those of the
27+
-- authors and should not be interpreted as representing official policies, either expressed
28+
-- or implied, of Michael Hoffer <[email protected]>.
29+
--
30+
-- Date: 25.12.16
31+
-- Time: 19:30
32+
-- Author: Michael Hoffer <[email protected]>
33+
--
34+
35+
-- script parameters
36+
fileName = $fileName$
37+
removeDoublesTOL = $removeDoublesTOL$
38+
resolveTOL = $resolveTOL$
39+
40+
41+
42+
-- check whether boundery edges exist
43+
function hasBoundaryEdges(meshP)
44+
45+
SelectBoundaryEdges(meshP)
46+
local vec_center = Vec3d()
47+
hasSelection = GetSelectionCenter(meshP,vec_center)
48+
49+
return hasSelection
50+
end
51+
52+
local mesh = Mesh()
53+
print("> loading "..fileName)
54+
if LoadMesh(mesh, fileName)==false then
55+
print(" -> ERROR while loading file.")
56+
end
57+
58+
SelectAll(mesh)
59+
60+
numRemoved = RemoveDoubles(mesh, removeDoublesTOL)
61+
62+
print("> removed "..numRemoved.." doubles with TOL "..removeDoublesTOL)
63+
64+
ClearSelection(mesh)
65+
66+
local counter = 0;
67+
local maxIter = 10;
68+
local tolInc = (resolveTOL-removeDoublesTOL)/maxIter
69+
70+
print("> fixing mesh (remove bnd-edges)")
71+
while hasBoundaryEdges(mesh) and counter < maxIter do
72+
local currentTol = removeDoublesTOL + tolInc*counter
73+
print(" -> attempt #"..counter.." with TOL "..currentTol)
74+
ResolveEdgeIntersection(mesh, currentTol)
75+
76+
SelectAll(mesh)
77+
78+
numRemoved = RemoveDoubles(mesh, currentTol)
79+
80+
print(" -> removed "..numRemoved.." doubles with TOL "..currentTol)
81+
82+
ClearSelection(mesh)
83+
counter=counter+1
84+
end
85+
86+
if counter >= maxIter then
87+
print(" -> ERROR while fixing mesh")
88+
do return 1 end -- quit with exit code
89+
end

0 commit comments

Comments
 (0)