def __init__(self, liaison, opts, prefix): SmoothNodes3DBg.__init__(self, liaison, opts) self.prefix = prefix self.liaison = liaison if self.prefix: MeshWriter.writeObject3D(liaison.getOutputMesh(), self.prefix + "0", None)
def writeVTK(liaison): global debug_write_counter if debug_write_counter: MeshWriter.writeObject3D(liaison.mesh, "/tmp/tmp.amibe", "") Amibe2VTK("/tmp/tmp.amibe").write("/tmp/m%i.vtp" % (debug_write_counter - 1)) debug_write_counter = debug_write_counter + 1
def afront(afront_path, tmp_dir, mesh, size, point_metric, immutable_groups, afront_stderr=None): from org.jcae.mesh.xmldata import AmibeReader, MultiDoubleFileReader """ Run afront and return a MultiDoubleFileReader allowing to read created nodes """ mesh_dir = os.path.join(tmp_dir, "mesh.amibe") if point_metric: metric_file = os.path.join(tmp_dir, "metric.bin") point_metric.save(metric_file) g_id = 1 MeshWriter.writeObject3D(mesh, mesh_dir, "") ar = AmibeReader.Dim3(mesh_dir) sm = ar.submeshes[0] nodes_file = os.path.join(tmp_dir, "nodes.bin") for g in sm.groups: if g.numberOfTrias == 0 or g.name in immutable_groups: f = open(nodes_file, 'ab') f.write('\0' * 4) f.close() continue cmd = [ afront_path, '-nogui', ':stdin', '-failsafe', 'false', '-resamp_bounds', 'false', '-lf_progress', 'true', '-stop_every', '10000', '-quiet', 'true', '-outname', nodes_file, '-idealNumThreads', '1' ] if point_metric: cmd.extend([ '-target_size', str(point_metric.getSize(g_id)), '-metric_file', metric_file ]) g_id = g_id + 1 else: cmd.extend(['-target_size', str(size)]) cmd.append('-tri_mesh') logstd = sys.stdout if afront_stderr is subprocess.STDOUT else sys.stderr logstd.write("meshing %s\n" % g.name) logstd.write(" ".join(cmd) + "\n") try: p = subprocess.Popen(cmd, stdin=subprocess.PIPE, cwd=tmp_dir, stderr=afront_stderr) sm.readGroup(g, p.stdin.fileno().channel) p.stdin.flush() return_code = p.wait() if return_code != 0: print "Exit code: " + str(return_code) except OSError: print "Cannot run afront" if os.path.isfile(nodes_file): return MultiDoubleFileReader(nodes_file) else: return
def afront_debug(afront_path, tmp_dir, mesh, size, point_metric, immutable_groups, afront_stderr=None, custom_options=None): from org.jcae.mesh.xmldata import Amibe2OFF, AFront2Amibe, AmibeReader, MultiDoubleFileReader """ Same as afront but with temporary files to help debugging """ if custom_options is None: custom_options = [] mesh_dir = os.path.join(tmp_dir, "mesh.amibe") if isinstance(point_metric, AbstractDistanceMetric): metric_file = os.path.join(tmp_dir, "metric.bin") point_metric.save(metric_file) g_id = 1 else: metric_file = None MeshWriter.writeObject3D(mesh, mesh_dir, "") ar = AmibeReader.Dim3(mesh_dir) sm = ar.submeshes[0] nodes_file = os.path.join(tmp_dir, "nodes.bin") for g in sm.groups: if g.numberOfTrias == 0 or g.name in immutable_groups: f = open(nodes_file, 'ab') f.write('\0' * 4) f.close() continue off_fn = tmp_dir + "/" + g.name + ".off" m_fn = tmp_dir + "/" + g.name + ".m" amibe_fn = tmp_dir + "/" + g.name + ".amibe" vtk_fn = tmp_dir + "/" + g.name + ".vtp" Amibe2OFF(ar).write(off_fn, g.name) cmd = [ afront_path, '-nogui', off_fn, '-failsafe', 'false', '-resamp_bounds', 'false', '-lf_progress', 'true', '-stop_every', '10000', '-quiet', 'true', '-outname', nodes_file, '-idealNumThreads', '1' ] + ([] if custom_options is None else custom_options) if metric_file: cmd.extend([ '-target_size', str(point_metric.getSize(g_id)), '-metric_file', metric_file ]) g_id = g_id + 1 else: cmd.extend(['-target_size', str(size)]) cmd.append('-tri_mesh') logstd = sys.stdout if afront_stderr is subprocess.STDOUT else sys.stderr logstd.write("meshing %s\n" % g.name) logstd.write(" ".join(cmd) + "\n") return_code = subprocess.call(cmd, cwd=tmp_dir, stderr=afront_stderr) if return_code != 0: print "Exit code: " + str(return_code) return MultiDoubleFileReader(nodes_file)
def afront_debug(afront_path, tmp_dir, mesh, size, point_metric, immutable_groups, afront_stderr=None): from org.jcae.mesh.xmldata import Amibe2OFF, AFront2Amibe, AmibeReader, MultiDoubleFileReader """ Same as afront but with temporary files to help debugging """ mesh_dir = os.path.join(tmp_dir, "mesh.amibe") if point_metric: metric_file = os.path.join(tmp_dir, "metric.bin") point_metric.save(metric_file) g_id = 1 MeshWriter.writeObject3D(mesh, mesh_dir, "") ar = AmibeReader.Dim3(mesh_dir) sm = ar.submeshes[0] nodes_file = os.path.join(tmp_dir, "nodes.bin") for g in sm.groups: if g.numberOfTrias == 0 or g.name in immutable_groups: f = open(nodes_file, "ab") f.write("\0" * 4) f.close() continue off_fn = tmp_dir + "/" + g.name + ".off" m_fn = tmp_dir + "/" + g.name + ".m" amibe_fn = tmp_dir + "/" + g.name + ".amibe" vtk_fn = tmp_dir + "/" + g.name + ".vtp" Amibe2OFF(ar).write(off_fn, g.name) cmd = [ afront_path, "-nogui", off_fn, "-failsafe", "false", "-resamp_bounds", "false", "-lf_progress", "true", "-stop_every", "10000", "-quiet", "true", "-outname", nodes_file, "-idealNumThreads", "1", ] if point_metric: cmd.extend(["-target_size", str(point_metric.getSize(g_id)), "-metric_file", metric_file]) g_id = g_id + 1 else: cmd.extend(["-target_size", str(size)]) cmd.append("-tri_mesh") logstd = sys.stdout if afront_stderr is subprocess.STDOUT else sys.stderr logstd.write("meshing %s\n" % g.name) logstd.write(" ".join(cmd) + "\n") return_code = subprocess.call(cmd, cwd=tmp_dir, stderr=afront_stderr) if return_code != 0: print "Exit code: " + str(return_code) return MultiDoubleFileReader(nodes_file)
def afront(afront_path, tmp_dir, mesh, size, point_metric, immutable_groups, afront_stderr = None, custom_options=None): from org.jcae.mesh.xmldata import AmibeReader, MultiDoubleFileReader """ Run afront and return a MultiDoubleFileReader allowing to read created nodes """ if custom_options is None: custom_options = [] mesh_dir = os.path.join(tmp_dir, "mesh.amibe") if isinstance(point_metric, AbstractDistanceMetric): metric_file = os.path.join(tmp_dir, "metric.bin") point_metric.save(metric_file) g_id = 1 else: metric_file = None MeshWriter.writeObject3D(mesh, mesh_dir, "") ar = AmibeReader.Dim3(mesh_dir) sm = ar.submeshes[0] nodes_file = os.path.join(tmp_dir, "nodes.bin") for g in sm.groups: if g.numberOfTrias == 0 or g.name in immutable_groups: f = open(nodes_file, 'ab') f.write('\0'*4) f.close() continue cmd = [afront_path, '-nogui', ':stdin', '-failsafe','false', '-resamp_bounds', 'false', '-lf_progress', 'true', '-stop_every', '10000', '-quiet', 'true', '-outname', nodes_file, '-idealNumThreads', '1'] + ([] if custom_options is None else custom_options) if metric_file: cmd.extend(['-target_size', str(point_metric.getSize(g_id)), '-metric_file', metric_file]) g_id = g_id + 1 else: cmd.extend(['-target_size', str(size)]) cmd.append('-tri_mesh') logstd = sys.stdout if afront_stderr is subprocess.STDOUT else sys.stderr logstd.write("meshing %s\n" % g.name) logstd.write(" ".join(cmd)+"\n") try: p = subprocess.Popen(cmd, stdin = subprocess.PIPE, cwd = tmp_dir, stderr = afront_stderr) sm.readGroup(g, p.stdin.fileno().channel) p.stdin.flush() return_code = p.wait() if return_code != 0: print "Exit code: "+str(return_code) except OSError: print "Cannot run afront" if os.path.isfile(nodes_file): return MultiDoubleFileReader(nodes_file) else: return
def afront_debug(afront_path, tmp_dir, mesh, size, point_metric, immutable_groups, afront_stderr = None, custom_options=None): from org.jcae.mesh.xmldata import Amibe2OFF, AFront2Amibe, AmibeReader, MultiDoubleFileReader """ Same as afront but with temporary files to help debugging """ if custom_options is None: custom_options = [] mesh_dir = os.path.join(tmp_dir, "mesh.amibe") if isinstance(point_metric, AbstractDistanceMetric): metric_file = os.path.join(tmp_dir, "metric.bin") point_metric.save(metric_file) g_id = 1 else: metric_file = None MeshWriter.writeObject3D(mesh, mesh_dir, "") ar = AmibeReader.Dim3(mesh_dir) sm = ar.submeshes[0] nodes_file = os.path.join(tmp_dir, "nodes.bin") for g in sm.groups: if g.numberOfTrias == 0 or g.name in immutable_groups: f = open(nodes_file, 'ab') f.write('\0'*4) f.close() continue off_fn = tmp_dir+"/"+g.name+".off" m_fn = tmp_dir+"/"+g.name+".m" amibe_fn = tmp_dir+"/"+g.name+".amibe" vtk_fn = tmp_dir+"/"+g.name+".vtp" Amibe2OFF(ar).write(off_fn, g.name) cmd = [afront_path, '-nogui', off_fn, '-failsafe','false', '-resamp_bounds', 'false', '-lf_progress', 'true', '-stop_every', '10000', '-quiet', 'true', '-outname', nodes_file, '-idealNumThreads', '1'] + ([] if custom_options is None else custom_options) if metric_file: cmd.extend(['-target_size', str(point_metric.getSize(g_id)), '-metric_file', metric_file]) g_id = g_id + 1 else: cmd.extend(['-target_size', str(size)]) cmd.append('-tri_mesh') logstd = sys.stdout if afront_stderr is subprocess.STDOUT else sys.stderr logstd.write("meshing %s\n" % g.name) logstd.write(" ".join(cmd)+"\n") return_code = subprocess.call(cmd, cwd = tmp_dir, stderr = afront_stderr) if return_code != 0: print "Exit code: "+str(return_code) return MultiDoubleFileReader(nodes_file)
def afront(afront_path, tmp_dir, mesh, size, point_metric, immutable_groups, afront_stderr = None): from org.jcae.mesh.xmldata import AmibeReader, MultiDoubleFileReader """ Run afront and return a MultiDoubleFileReader allowing to read created nodes """ mesh_dir = os.path.join(tmp_dir, "mesh.amibe") if point_metric: metric_file = os.path.join(tmp_dir, "metric.bin") point_metric.save(metric_file) g_id = 1 MeshWriter.writeObject3D(mesh, mesh_dir, "") ar = AmibeReader.Dim3(mesh_dir) sm = ar.submeshes[0] nodes_file = os.path.join(tmp_dir, "nodes.bin") for g in sm.groups: if g.numberOfTrias == 0 or g.name in immutable_groups: f = open(nodes_file, 'ab') f.write('\0'*4) f.close() continue cmd = [afront_path, '-nogui', ':stdin', '-failsafe','false', '-resamp_bounds', 'false', '-lf_progress', 'true', '-stop_every', '10000', '-quiet', 'true', '-outname', nodes_file] if point_metric: cmd.extend(['-target_size', str(point_metric.getSize(g_id)), '-metric_file', metric_file]) g_id = g_id + 1 else: cmd.extend(['-target_size', str(size)]) cmd.append('-tri_mesh') sys.stderr.write("meshing %s\n" % g.name) sys.stderr.write(" ".join(cmd)+"\n") p = subprocess.Popen(cmd, stdin = subprocess.PIPE, cwd = tmp_dir, stderr = afront_stderr) sm.readGroup(g, p.stdin.fileno().channel) p.stdin.flush() return_code = p.wait() if return_code != 0: print "Exit code: "+str(return_code) return MultiDoubleFileReader(nodes_file)
def remesh(**kwargs): """Remesh beams of an existing mesh with a singular analytical metric It is necessary to remove J_ and G_ groups for wires. """ # Build background mesh try: liaison = kwargs["liaison"] except KeyError: mtb = MeshTraitsBuilder.getDefault3D() mtb.addNodeSet() mesh = Mesh(mtb) MeshReader.readObject3D(mesh, kwargs["in_dir"]) liaison = MeshLiaison.create(mesh, mtb) immutable_groups = list() if kwargs["immutable_groups_file"]: f = open(kwargs["immutable_groups_file"]) immutable_groups = f.read().split() f.close() liaison.mesh.tagGroups(immutable_groups, AbstractHalfEdge.IMMUTABLE) liaison = remesh_beams(liaison, kwargs["size"], kwargs["rho"], immutable_groups, kwargs["point_metric_file"]) # Output MeshWriter.writeObject3D(liaison.getMesh(), kwargs["out_dir"], "")
def afront(afront_path, tmp_dir, mesh, size, point_metric, immutable_groups, afront_stderr=None): from org.jcae.mesh.xmldata import AmibeReader, MultiDoubleFileReader """ Run afront and return a MultiDoubleFileReader allowing to read created nodes """ mesh_dir = os.path.join(tmp_dir, "mesh.amibe") if point_metric: metric_file = os.path.join(tmp_dir, "metric.bin") point_metric.save(metric_file) g_id = 1 MeshWriter.writeObject3D(mesh, mesh_dir, "") ar = AmibeReader.Dim3(mesh_dir) sm = ar.submeshes[0] nodes_file = os.path.join(tmp_dir, "nodes.bin") for g in sm.groups: if g.numberOfTrias == 0 or g.name in immutable_groups: f = open(nodes_file, "ab") f.write("\0" * 4) f.close() continue cmd = [ afront_path, "-nogui", ":stdin", "-failsafe", "false", "-resamp_bounds", "false", "-lf_progress", "true", "-stop_every", "10000", "-quiet", "true", "-outname", nodes_file, "-idealNumThreads", "1", ] if point_metric: cmd.extend(["-target_size", str(point_metric.getSize(g_id)), "-metric_file", metric_file]) g_id = g_id + 1 else: cmd.extend(["-target_size", str(size)]) cmd.append("-tri_mesh") logstd = sys.stdout if afront_stderr is subprocess.STDOUT else sys.stderr logstd.write("meshing %s\n" % g.name) logstd.write(" ".join(cmd) + "\n") try: p = subprocess.Popen(cmd, stdin=subprocess.PIPE, cwd=tmp_dir, stderr=afront_stderr) sm.readGroup(g, p.stdin.fileno().channel) p.stdin.flush() return_code = p.wait() if return_code != 0: print "Exit code: " + str(return_code) except OSError: print "Cannot run afront" if os.path.isfile(nodes_file): return MultiDoubleFileReader(nodes_file) else: return
help= "minimum dot product of face normals when building feature edges (default 0.95)" ) (options, args) = parser.parse_args(args=sys.argv[1:]) if len(args) != 2: parser.print_usage() sys.exit(1) xmlDir = args[0] outDir = args[1] mtb = MeshTraitsBuilder.getDefault3D() mtb.addNodeSet() mesh = Mesh(mtb) MeshReader.readObject3D(mesh, xmlDir) liaison = MeshLiaison.create(mesh, mtb) if options.coplanarity: liaison.getMesh().buildRidges(options.coplanarity) if options.preserveGroups: liaison.getMesh().buildGroupBoundaries() opts = HashMap() if options.coplanarity: opts.put("coplanarity", str(options.coplanarity)) opts.put("checkNormals", str("false")) ImproveVertexValence(liaison, opts).compute() MeshWriter.writeObject3D(liaison.getMesh(), outDir, String())
SwapEdge(liaison, opts).compute() writeVTK(liaison) opts.clear() opts.put("coplanarity", "0.75") opts.put("tolerance", "0.6") opts.put("iterations", str(8)) SmoothNodes3DBg(liaison, opts).compute() writeVTK(liaison) #MeshWriter.writeObject3D(liaison.mesh, outDir, "" polylines = PolylineFactory(liaison.mesh, 135.0, options.size * 0.2) liaison.mesh.resetBeams() for entry in polylines.entrySet(): groupId = entry.key for polyline in entry.value: listM = ArrayList() for v in polyline: listM.add(EuclidianMetric3D(options.size)) #print "Remesh polyline of group "+str(groupId)+"/"+str(polylines.size())+" "+str(polyline.size())+" vertices" result = RemeshPolyline(liaison.mesh, polyline, listM).compute() for i in xrange(result.size() - 1): liaison.mesh.addBeam(result.get(i), result.get(i + 1), groupId) #print " New polyline: "+str(result.size())+" vertices" if options.recordFile: liaison.getMesh().getTrace().finish() MeshWriter.writeObject3D(liaison.mesh, outDir, "")
def postProcessIteration(self, mesh, counter, *args): if self.prefix: MeshWriter.writeObject3D(mesh, self.prefix + str(counter), None)
sys.exit(1) vtpFile = args[0] outDir = args[1] Utils.loadVTKLibraries() reader = vtkXMLPolyDataReader() reader.SetFileName(vtpFile) reader.Update() polydata = reader.GetOutput() mesh = Mesh(MeshTraitsBuilder()) vertices = jarray.zeros(polydata.GetNumberOfPoints(), Vertex) coord = jarray.zeros(3, "d") for i in xrange(len(vertices)): polydata.GetPoint(i, coord) vertices[i] = mesh.createVertex(coord) indices = Utils.getValues(polydata.GetPolys()) i = 0 while i < len(indices): if (indices[i] == 3): mesh.add(mesh.createTriangle( vertices[indices[i+1]], vertices[indices[i+2]], vertices[indices[i+3]])) i += indices[i] + 1 MeshWriter.writeObject3D(mesh, outDir, String())
def writeVTK(liaison): global debug_write_counter if debug_write_counter: MeshWriter.writeObject3D(liaison.mesh, "/tmp/tmp.amibe", "") Amibe2VTK("/tmp/tmp.amibe").write("/tmp/m%i.vtp" % (debug_write_counter-1)); debug_write_counter=debug_write_counter+1
if lastVertex != vertices.get(2*b): # New polyline polyline = ArrayList() listOfPolylines.add(polyline) polyline.add(vertices.get(2*b)) lastVertex = vertices.get(2*b+1) polyline.add(lastVertex) print "Group "+str(bId)+" contains "+str(listOfPolylines.size())+" polylines and "+str(listBeamId.size()+1)+" vertices" mapGroupToListOfPolylines.put(bId, listOfPolylines) for bId in bgroupMap.keySet(): listBeamId = bgroupMap.get(bId) listOfPolylines = mapGroupToListOfPolylines.get(bId) nrPoly = listOfPolylines.size() for numPoly in xrange(nrPoly): polyline = listOfPolylines.get(numPoly) listM = ArrayList() for v in polyline: listM.add(EuclidianMetric3D(size)) #for v in polyline: # print v print "Remesh polyline "+str(numPoly+1)+"/"+str(nrPoly)+" of group "+str(bId)+"/"+str(bgroupMap.size())+" "+str(polyline.size())+" vertices" result = RemeshPolyline(mesh, polyline, listM).compute() for i in xrange(result.size() - 1): mesh.addBeam(result.get(i), result.get(i+1), bId) print " New polyline: "+str(result.size())+" vertices" #for v in result: # print v MeshWriter.writeObject3D(mesh, outDir, "")
def postProcessIteration(self, mesh, counter, *args): if self.prefix: MeshWriter.writeObject3D(mesh, self.prefix + str(counter), None);
def postProcessIteration(self, liaison, counter, *args): if self.prefix: MeshWriter.writeObject3D(liaison.getOutputMesh(), self.prefix + str(counter + 1), None)
SwapEdge(liaison, opts).compute() writeVTK(liaison) opts.clear() opts.put("coplanarity", "0.75") opts.put("tolerance", "0.6") opts.put("iterations", str(8)) SmoothNodes3DBg(liaison, opts).compute() writeVTK(liaison) #MeshWriter.writeObject3D(liaison.mesh, outDir, "" polylines=PolylineFactory(liaison.mesh, 135.0, options.size*0.2) liaison.mesh.resetBeams() for entry in polylines.entrySet(): groupId = entry.key for polyline in entry.value: listM = ArrayList() for v in polyline: listM.add(EuclidianMetric3D(options.size)) #print "Remesh polyline of group "+str(groupId)+"/"+str(polylines.size())+" "+str(polyline.size())+" vertices" result = RemeshPolyline(liaison.mesh, polyline, listM).compute() for i in xrange(result.size() - 1): liaison.mesh.addBeam(result.get(i), result.get(i+1), groupId) #print " New polyline: "+str(result.size())+" vertices" if options.recordFile: liaison.getMesh().getTrace().finish() MeshWriter.writeObject3D(liaison.mesh, outDir, "")
def __remesh(options): afront_stderr = getattr(options, 'afront_stderr', None) mesh = getattr(options, 'mesh', None) liaison = getattr(options, 'liaison', None) if not liaison: if not mesh: mesh = create_mesh(**options) liaison = MeshLiaison.create(mesh) if options.recordFile: liaison.getMesh().getTrace().setDisabled(False) liaison.getMesh().getTrace().setLogFile(options.recordFile) liaison.getMesh().getTrace().createMesh("mesh", liaison.getMesh()) if options.immutable_border: liaison.mesh.tagFreeEdges(AbstractHalfEdge.IMMUTABLE) liaison.getMesh().buildRidges(options.coplanarity) if options.immutable_border_group: liaison.mesh.tagGroupBoundaries(AbstractHalfEdge.IMMUTABLE) else: if options.preserveGroups: liaison.getMesh().buildGroupBoundaries() immutable_groups = [] if options.immutable_groups_file: immutable_groups = read_groups(options.immutable_groups_file) liaison.mesh.tagGroups(immutable_groups, AbstractHalfEdge.IMMUTABLE) if options.point_metric_file: point_metric = DistanceMetric(options.size, options.point_metric_file) elif getattr(options, 'point_metric', None): point_metric = options.point_metric else: point_metric = None safe_coplanarity = str(max(options.coplanarity, 0.8)) if options.forced_points: if point_metric: vi = VertexInsertion(liaison, point_metric) else: vi = VertexInsertion(liaison, options.size) vi.insertNodes(options.forced_points, -1) Vertex.setMutable(vi.mutableInserted, False) #0 writeVTK(liaison) if options.boundary_angle == None: options.boundary_angle = 1.66 if point_metric: point_metric.scaling = 1 if options.forced_bounds: BeamInsertion(liaison.mesh, point_metric).insert( options.forced_bounds[0], options.forced_bounds[1]) RemeshSkeleton(liaison, options.boundary_angle, options.size / 100.0, point_metric).compute() else: RemeshSkeleton(liaison, options.boundary_angle, options.size / 100.0, options.size).compute() if options.forced_bounds: BeamInsertion(liaison.mesh, options.size).insert( options.forced_bounds[0], options.forced_bounds[1]) #1 writeVTK(liaison) opts = HashMap() opts.put("coplanarity", safe_coplanarity) # Swapping here will help QEMDecimateHalfEdge to decimate more and will # reduce the risk to have edge not processed by LengthDecimateHalfEdge algo = SwapEdge(liaison, opts) algo.maxSwapVolume = (options.size / 4.0)**3 algo.compute() #2 writeVTK(liaison) if options.recordFile: cmds = [ String("assert self.m.checkNoDegeneratedTriangles()"), String("assert self.m.checkNoInvertedTriangles()"), String("assert self.m.checkVertexLinks()"), String("assert self.m.isValid()") ] liaison.getMesh().getTrace().setHooks(cmds) opts.clear() opts.put("coplanarity", str(options.coplanarity)) opts.put("size", str(options.size*0.3)) opts.put("maxlength", str(options.size*sqrt(2))) #workaround for a QEMDecimateHalfEdge bug opts.put("freezeNonManifold", "true") algo = QEMDecimateHalfEdge(liaison, opts) if point_metric: point_metric.scaling = sqrt(2) algo.analyticMetric = point_metric algo.compute() #3 # afront call writeVTK(liaison) afront_nodes_reader = None afront_frozen = None if options.afront_path: tmp_dir = tempfile.mkdtemp() afront_nodes_reader = afront(options.afront_path, tmp_dir, liaison.mesh, options.size, point_metric, immutable_groups, afront_stderr = afront_stderr) afront_frozen = afront_insert(liaison, afront_nodes_reader, options.size, point_metric) Vertex.setMutable(afront_frozen, False) shutil.rmtree(tmp_dir, ignore_errors=True) #4 writeVTK(liaison) if options.afront_path: opts.clear() opts.put("expectInsert", "false") opts.put("coplanarity", safe_coplanarity) SwapEdge(liaison, opts).compute() #5 writeVTK(liaison) opts.clear() opts.put("size", str(options.size)) opts.put("freeEdgesOnly", "true") opts.put("coplanarity", "-2") algo = LengthDecimateHalfEdge(liaison, opts) if point_metric: algo.analyticMetric = point_metric algo.compute() #6 writeVTK(liaison) opts.clear() opts.put("size", str(options.size)) opts.put("coplanarity", str(options.coplanarity)) opts.put("minCosAfterSwap", "0.3") opts.put("nearLengthRatio", "0.6") algo = Remesh(liaison, opts) if point_metric: point_metric.scaling = 1 algo.analyticMetric = point_metric algo.compute() #7 writeVTK(liaison) opts.clear() opts.put("coplanarity", safe_coplanarity) opts.put("expectInsert", "false" if options.afront_path else "true") SwapEdge(liaison, opts).compute() #8 writeVTK(liaison) opts.clear() opts.put("coplanarity", str(options.coplanarity)) opts.put("iterations", "2") opts.put("size", str(options.size)) algo = SmoothNodes3DBg(liaison, opts) algo.compute() #9 writeVTK(liaison) opts.clear() opts.put("coplanarity", str(options.coplanarity)) opts.put("expectInsert", "false" if options.afront_path else "true") opts.put("minCosAfterSwap", "0.3") algo = SwapEdge(liaison, opts) algo.angleQualityRatio = 150 algo.compute() #10 writeVTK(liaison) if not options.afront_path: opts.clear() opts.put("size", str(options.size)) algo = Remesh(liaison, opts) algo.analyticMetric = point_metric algo.compute() #11 writeVTK(liaison) opts.clear() opts.put("coplanarity", str(options.coplanarity)) opts.put("size", str(options.size*0.3)) opts.put("maxlength", str(options.size*sqrt(2))) #workaround for a QEMDecimateHalfEdge bug opts.put("freezeNonManifold", "true") algo = QEMDecimateHalfEdge(liaison, opts) if point_metric: point_metric.scaling = sqrt(2) algo.analyticMetric = point_metric algo.compute() #12 writeVTK(liaison) opts.clear() opts.put("coplanarity", str(options.coplanarity)) opts.put("expectInsert", "false" if options.afront_path else "true") opts.put("minCosAfterSwap", "0.3") algo = SwapEdge(liaison, opts) algo.angleQualityRatio = 150 algo.compute() #13 writeVTK(liaison) if afront_frozen: Vertex.setMutable(afront_frozen, True) opts.clear() opts.put("checkNormals", "false") ImproveVertexValence(liaison, opts).compute() #14 writeVTK(liaison) opts.clear() opts.put("coplanarity", safe_coplanarity) opts.put("iterations", str(8)) algo = SmoothNodes3DBg(liaison, opts) algo.compute() #15 writeVTK(liaison) #MeshWriter.writeObject3D(liaison.mesh, outDir, "" polylines=PolylineFactory(liaison.mesh, 135.0, options.size*0.2) liaison.mesh.resetBeams() for entry in polylines.entrySet(): groupId = entry.key for polyline in entry.value: listM = ArrayList() for v in polyline: listM.add(EuclidianMetric3D(options.size)) #print "Remesh polyline of group "+str(groupId)+"/"+str(polylines.size())+" "+str(polyline.size())+" vertices" if liaison.mesh.getGroupName(groupId) in immutable_groups: result = polyline elif point_metric: result = RemeshPolyline(liaison.mesh, polyline, point_metric).compute() else: result = RemeshPolyline(liaison.mesh, polyline, listM).compute() for i in xrange(result.size() - 1): liaison.mesh.addBeam(result.get(i), result.get(i+1), groupId) #print " New polyline: "+str(result.size())+" vertices" if options.recordFile: liaison.getMesh().getTrace().finish() if options.post_script: execfile(options.post_script) if options.out_dir: MeshWriter.writeObject3D(liaison.mesh, options.out_dir, "")
def remesh(**kwargs): """ Remesh an existing mesh with a singular analytical metric """ # Process coplanarity options coplanarity = cos(kwargs["coplanarityAngle"] * pi / 180.0) if kwargs["coplanarity"]: coplanarity = kwargs["coplanarity"] safe_coplanarity = kwargs["safe_coplanarity"] if safe_coplanarity is None: safe_coplanarity = 0.8 safe_coplanarity = max(coplanarity, safe_coplanarity) # Build background mesh try: liaison = kwargs["liaison"] except KeyError: mtb = MeshTraitsBuilder.getDefault3D() if kwargs["recordFile"]: mtb.addTraceRecord() mtb.addNodeSet() mesh = Mesh(mtb) if kwargs["recordFile"]: mesh.getTrace().setDisabled(True) MeshReader.readObject3D(mesh, kwargs["in_dir"]) liaison = MeshLiaison.create(mesh, mtb) if kwargs["recordFile"]: liaison.getMesh().getTrace().setDisabled(False) liaison.getMesh().getTrace().setLogFile(kwargs["recordFile"]) liaison.getMesh().getTrace().createMesh("mesh", liaison.getMesh()) if kwargs["immutable_border"]: liaison.mesh.tagFreeEdges(AbstractHalfEdge.IMMUTABLE) liaison.getMesh().buildRidges(coplanarity) if kwargs["preserveGroups"]: liaison.getMesh().buildGroupBoundaries() immutable_groups = [] if kwargs["immutable_groups_file"]: f = open(kwargs["immutable_groups_file"]) immutable_groups = f.read().split() f.close() liaison.mesh.tagGroups(immutable_groups, AbstractHalfEdge.IMMUTABLE) if kwargs["recordFile"]: cmds = [ String("assert self.m.checkNoDegeneratedTriangles()"), String("assert self.m.checkNoInvertedTriangles()"), String("assert self.m.checkVertexLinks()"), String("assert self.m.isValid()"), ] liaison.getMesh().getTrace().setHooks(cmds) # Decimate if kwargs["decimateSize"] or kwargs["decimateTarget"]: decimateOptions = HashMap() if kwargs["decimateSize"]: decimateOptions.put("size", str(kwargs["decimateSize"])) elif kwargs["decimateTarget"]: decimateOptions.put("maxtriangles", str(kwargs["decimateTarget"])) decimateOptions.put("coplanarity", str(safe_coplanarity)) QEMDecimateHalfEdge(liaison, decimateOptions).compute() swapOptions = HashMap() swapOptions.put("coplanarity", str(safe_coplanarity)) SwapEdge(liaison, swapOptions).compute() # Metric if kwargs["rho"] > 1.0: # mixed metric metric = SingularMetric(kwargs["sizeinf"], kwargs["point_metric_file"], kwargs["rho"], True) else: # analytic metric metric = SingularMetric(kwargs["sizeinf"], kwargs["point_metric_file"]) # Remesh Skeleton if kwargs["skeleton"]: RemeshSkeleton(liaison, 1.66, metric, 0.01).compute() # Remesh refineOptions = HashMap() refineOptions.put("size", str(kwargs["sizeinf"])) refineOptions.put("coplanarity", str(safe_coplanarity)) refineOptions.put("nearLengthRatio", str(kwargs["nearLengthRatio"])) refineOptions.put("project", "false") if kwargs["allowNearNodes"]: refineOptions.put("allowNearNodes", "true") refineAlgo = Remesh(liaison, refineOptions) refineAlgo.setAnalyticMetric(metric) refineAlgo.compute() if not kwargs["noclean"]: # Swap swapOptions = HashMap() swapOptions.put("coplanarity", str(safe_coplanarity)) swapOptions.put("minCosAfterSwap", "0.3") SwapEdge(liaison, swapOptions).compute() # Improve valence valenceOptions = HashMap() valenceOptions.put("coplanarity", str(safe_coplanarity)) valenceOptions.put("checkNormals", "false") ImproveVertexValence(liaison, valenceOptions).compute() # Smooth smoothOptions = HashMap() smoothOptions.put("iterations", str(8)) smoothOptions.put("check", "true") smoothOptions.put("boundaries", "true") smoothOptions.put("relaxation", str(0.6)) if safe_coplanarity >= 0.0: smoothOptions.put("coplanarity", str(safe_coplanarity)) SmoothNodes3DBg(liaison, smoothOptions).compute() # Remove Degenerated rdOptions = HashMap() rdOptions.put("rho", str(kwargs["eratio"])) RemoveDegeneratedTriangles(liaison, rdOptions).compute() # remesh beams if kwargs["wire_size"] > 0.0: liaison = remesh_beams( liaison=liaison, size=kwargs["wire_size"], rho=kwargs["rho"], immutable_groups=immutable_groups, point_metric_file=kwargs["wire_metric_file"], ) # Output MeshWriter.writeObject3D(liaison.getMesh(), kwargs["out_dir"], "") if kwargs["recordFile"]: liaison.getMesh().getTrace().finish()
def __remesh(options): afront_stderr = getattr(options, 'afront_stderr', None) mesh = getattr(options, 'mesh', None) liaison = getattr(options, 'liaison', None) if not liaison: if not mesh: mesh = create_mesh(**options) liaison = MeshLiaison.create(mesh) if options.recordFile: liaison.getMesh().getTrace().setDisabled(False) liaison.getMesh().getTrace().setLogFile(options.recordFile) liaison.getMesh().getTrace().createMesh("mesh", liaison.getMesh()) if options.immutable_border: liaison.mesh.tagFreeEdges(AbstractHalfEdge.IMMUTABLE) liaison.getMesh().buildRidges(options.coplanarity) if options.immutable_border_group: liaison.mesh.tagGroupBoundaries(AbstractHalfEdge.IMMUTABLE) else: if options.preserveGroups: liaison.getMesh().buildGroupBoundaries() immutable_groups = [] if options.immutable_groups_file: immutable_groups = read_groups(options.immutable_groups_file) liaison.mesh.tagGroups(immutable_groups, AbstractHalfEdge.IMMUTABLE) if options.point_metric_file: point_metric = DistanceMetric(options.size, options.point_metric_file) elif getattr(options, 'point_metric', None): point_metric = options.point_metric else: point_metric = None safe_coplanarity = str(max(options.coplanarity, 0.8)) if options.forced_points: if point_metric: vi = VertexInsertion(liaison, point_metric) else: vi = VertexInsertion(liaison, options.size) vi.insertNodes(options.forced_points, -1) Vertex.setMutable(vi.mutableInserted, False) #0 writeVTK(liaison) if options.boundary_angle == None: options.boundary_angle = 1.66 if point_metric: point_metric.scaling = 1 if options.forced_bounds: BeamInsertion(liaison.mesh, point_metric).insert(options.forced_bounds[0], options.forced_bounds[1]) RemeshSkeleton(liaison, options.boundary_angle, options.size / 100.0, point_metric).compute() else: RemeshSkeleton(liaison, options.boundary_angle, options.size / 100.0, options.size).compute() if options.forced_bounds: BeamInsertion(liaison.mesh, options.size).insert(options.forced_bounds[0], options.forced_bounds[1]) #1 writeVTK(liaison) opts = HashMap() opts.put("coplanarity", safe_coplanarity) # Swapping here will help QEMDecimateHalfEdge to decimate more and will # reduce the risk to have edge not processed by LengthDecimateHalfEdge algo = SwapEdge(liaison, opts) algo.maxSwapVolume = (options.size / 4.0)**3 algo.compute() #2 writeVTK(liaison) if options.recordFile: cmds = [ String("assert self.m.checkNoDegeneratedTriangles()"), String("assert self.m.checkNoInvertedTriangles()"), String("assert self.m.checkVertexLinks()"), String("assert self.m.isValid()") ] liaison.getMesh().getTrace().setHooks(cmds) opts.clear() opts.put("coplanarity", str(options.coplanarity)) opts.put("size", str(options.size * 0.3)) opts.put("maxlength", str(options.size * sqrt(2))) #workaround for a QEMDecimateHalfEdge bug opts.put("freezeNonManifold", "true") algo = QEMDecimateHalfEdge(liaison, opts) if point_metric: point_metric.scaling = sqrt(2) algo.analyticMetric = point_metric algo.compute() #3 # afront call writeVTK(liaison) afront_nodes_reader = None afront_frozen = None if options.afront_path: tmp_dir = tempfile.mkdtemp() afront_nodes_reader = afront(options.afront_path, tmp_dir, liaison.mesh, options.size, point_metric, immutable_groups, afront_stderr=afront_stderr) afront_frozen = afront_insert(liaison, afront_nodes_reader, options.size, point_metric) Vertex.setMutable(afront_frozen, False) #4 writeVTK(liaison) if options.afront_path: opts.clear() opts.put("expectInsert", "false") opts.put("coplanarity", safe_coplanarity) SwapEdge(liaison, opts).compute() #5 writeVTK(liaison) opts.clear() opts.put("size", str(options.size)) opts.put("freeEdgesOnly", "true") opts.put("coplanarity", "-2") algo = LengthDecimateHalfEdge(liaison, opts) if point_metric: algo.analyticMetric = point_metric algo.compute() #6 writeVTK(liaison) opts.clear() opts.put("size", str(options.size)) opts.put("coplanarity", str(options.coplanarity)) opts.put("minCosAfterSwap", "0.3") opts.put("nearLengthRatio", "0.6") algo = Remesh(liaison, opts) if point_metric: point_metric.scaling = 1 algo.analyticMetric = point_metric algo.compute() #7 writeVTK(liaison) opts.clear() opts.put("coplanarity", safe_coplanarity) opts.put("expectInsert", "false" if options.afront_path else "true") SwapEdge(liaison, opts).compute() #8 writeVTK(liaison) opts.clear() opts.put("coplanarity", str(options.coplanarity)) opts.put("iterations", "2") opts.put("size", str(options.size)) algo = SmoothNodes3DBg(liaison, opts) algo.compute() #9 writeVTK(liaison) opts.clear() opts.put("coplanarity", str(options.coplanarity)) opts.put("expectInsert", "false" if options.afront_path else "true") opts.put("minCosAfterSwap", "0.3") SwapEdge(liaison, opts).compute() #10 writeVTK(liaison) if not options.afront_path: opts.clear() opts.put("size", str(options.size)) algo = Remesh(liaison, opts) algo.analyticMetric = point_metric algo.compute() #11 writeVTK(liaison) opts.clear() opts.put("coplanarity", str(options.coplanarity)) opts.put("size", str(options.size * 0.3)) opts.put("maxlength", str(options.size * sqrt(2))) #workaround for a QEMDecimateHalfEdge bug opts.put("freezeNonManifold", "true") algo = QEMDecimateHalfEdge(liaison, opts) if point_metric: point_metric.scaling = sqrt(2) algo.analyticMetric = point_metric algo.compute() #12 writeVTK(liaison) opts.clear() opts.put("coplanarity", str(options.coplanarity)) opts.put("expectInsert", "false" if options.afront_path else "true") opts.put("minCosAfterSwap", "0.3") SwapEdge(liaison, opts).compute() #13 writeVTK(liaison) if afront_frozen: Vertex.setMutable(afront_frozen, True) opts.clear() opts.put("checkNormals", "false") ImproveVertexValence(liaison, opts).compute() #14 writeVTK(liaison) opts.clear() opts.put("coplanarity", safe_coplanarity) opts.put("iterations", str(8)) algo = SmoothNodes3DBg(liaison, opts) algo.compute() #15 writeVTK(liaison) #MeshWriter.writeObject3D(liaison.mesh, outDir, "" polylines = PolylineFactory(liaison.mesh, 135.0, options.size * 0.2) liaison.mesh.resetBeams() for entry in polylines.entrySet(): groupId = entry.key for polyline in entry.value: listM = ArrayList() for v in polyline: listM.add(EuclidianMetric3D(options.size)) #print "Remesh polyline of group "+str(groupId)+"/"+str(polylines.size())+" "+str(polyline.size())+" vertices" if liaison.mesh.getGroupName(groupId) in immutable_groups: result = polyline else: result = RemeshPolyline(liaison.mesh, polyline, listM).compute() for i in xrange(result.size() - 1): liaison.mesh.addBeam(result.get(i), result.get(i + 1), groupId) #print " New polyline: "+str(result.size())+" vertices" if options.recordFile: liaison.getMesh().getTrace().finish() if options.post_script: execfile(options.post_script) MeshWriter.writeObject3D(liaison.mesh, options.out_dir, "")
liaison.getMesh().getTrace().setLogFile(options.recordFile) liaison.getMesh().getTrace().createMesh("mesh", liaison.getMesh()) if options.immutable_border: liaison.mesh.tagFreeEdges(AbstractHalfEdge.IMMUTABLE) if options.coplanarity: liaison.getMesh().buildRidges(options.coplanarity) if options.preserveGroups: liaison.getMesh().buildGroupBoundaries() opts = HashMap() opts.put("iterations", str(options.iterations)) opts.put("boundaries", str(options.boundaries)) opts.put("check", str(options.check)) opts.put("size", str(options.size)) opts.put("tolerance", str(options.tolerance)) opts.put("relaxation", str(options.relaxation)) opts.put("refresh", str(options.refresh)) if (options.coplanarity >= 0.0): opts.put("coplanarity", str(options.coplanarity)) if options.prefix: sm = MySmoothNodes3DBg(liaison, opts, options.prefix) else: sm = SmoothNodes3DBg(liaison, opts) sm.setProgressBarStatus(10000) sm.compute() if options.recordFile: liaison.getMesh().getTrace().finish() MeshWriter.writeObject3D(sm.getOutputMesh(), outDir, String())
def afterSwapHook(self): if self.ridges: self.liaison.getMesh().createRidgesGroup("ridges") MeshWriter.writeObject3D(self.liaison.getMesh(), "DEBUG" + str(self.cnt), String()) self.cnt += 1
if (coplanarity >= 0.0): smoothOptions.put("coplanarity", str(coplanarity)) SmoothNodes3DBg(liaison, smoothOptions).compute() ## Remove Degenerated rdOptions = HashMap() rdOptions.put("rho", str(options.eratio)) RemoveDegeneratedTriangles(liaison, rdOptions).compute() ## Remesh beams if options.wire > 0.0: polylines = PolylineFactory(liaison.mesh, 135.0, options.wire*0.2) liaison.mesh.resetBeams() for entry in polylines.entrySet(): groupId = entry.key for polyline in entry.value: listM = ArrayList() for v in polyline: listM.add(EuclidianMetric3D(options.wire)) if liaison.mesh.getGroupName(groupId) in immutable_groups: result = polyline else: result = RemeshPolyline(liaison.mesh, polyline, listM).compute() for i in xrange(result.size() - 1): liaison.mesh.addBeam(result.get(i), result.get(i+1), groupId) ## Output MeshWriter.writeObject3D(liaison.getMesh(), outDir, "") if options.recordFile: liaison.getMesh().getTrace().finish()
def postProcessIteration(self, liaison, counter, *args): if self.prefix: MeshWriter.writeObject3D(liaison.getOutputMesh(), self.prefix + str(counter+1), None)
cmd = ("partition ", "<inputDir> <outputDir>", "Automatic partitioning of a mesh, based on feature edges") parser = OptionParser(usage="amibebatch %s [OPTIONS] %s\n\n%s" % cmd, prog="report") parser.add_option( "-c", "--coplanarity", metavar="FLOAT", default=0.95, action="store", type="float", dest="coplanarity", help= "minimum dot product of face normals when building feature edges (default 0.95)" ) (options, args) = parser.parse_args(args=sys.argv[1:]) if len(args) != 2: parser.print_usage() sys.exit(1) xmlDir = args[0] outDir = args[1] mesh = Mesh() MeshReader.readObject3D(mesh, xmlDir) mesh.buildRidges(options.coplanarity) mesh.buildPartition() MeshWriter.writeObject3D(mesh, outDir, String())
def afterSwapHook(self): if self.ridges: self.liaison.getMesh().createRidgesGroup("ridges") MeshWriter.writeObject3D(self.liaison.getMesh(), "DEBUG"+str(self.cnt), String()) self.cnt += 1
mtb.addTraceRecord() mesh = Mesh(mtb) if options.recordFile: mesh.getTrace().setDisabled(True) MeshReader.readObject3D(mesh, xmlDir) assert mesh.isValid() liaison = MeshLiaison(mesh, mtb) if options.recordFile: liaison.getMesh().getTrace().setDisabled(False) liaison.getMesh().getTrace().setLogFile(options.recordFile) liaison.getMesh().getTrace().createMesh("mesh", liaison.getMesh()) if options.coplanarity: liaison.getMesh().buildRidges(options.coplanarity) if options.immutable_border: liaison.mesh.tagFreeEdges(AbstractHalfEdge.IMMUTABLE) if options.immutable_border_group: liaison.mesh.tagGroupBoundaries(AbstractHalfEdge.IMMUTABLE) else: if options.preserveGroups: liaison.getMesh().buildGroupBoundaries() cons = Class.forName("org.jcae.mesh.amibe.algos3d."+options.algorithm).getConstructor([ MeshLiaison, Map ]) cons.newInstance([ liaison, opts ]).compute() if options.recordFile: liaison.getMesh().getTrace().finish() MeshWriter.writeObject3D(liaison.getMesh(), outDir, String())
liaison.getMesh().getTrace().setDisabled(False) liaison.getMesh().getTrace().setLogFile(options.recordFile) liaison.getMesh().getTrace().createMesh("mesh", liaison.getMesh()) if options.immutable_border: liaison.mesh.tagFreeEdges(AbstractHalfEdge.IMMUTABLE) if options.coplanarity: liaison.getMesh().buildRidges(options.coplanarity) if options.preserveGroups: liaison.getMesh().buildGroupBoundaries() opts = HashMap() opts.put("iterations", str(options.iterations)) opts.put("boundaries", str(options.boundaries)) opts.put("check", str(options.check)) opts.put("size", str(options.size)) opts.put("tolerance", str(options.tolerance)) opts.put("relaxation", str(options.relaxation)) opts.put("refresh", str(options.refresh)) if (options.coplanarity >= 0.0): opts.put("coplanarity", str(options.coplanarity)) if options.prefix: sm = MySmoothNodes3DBg(liaison, opts, options.prefix) else: sm = SmoothNodes3DBg(liaison, opts) sm.setProgressBarStatus(10000) sm.compute() if options.recordFile: liaison.getMesh().getTrace().finish() MeshWriter.writeObject3D(sm.getOutputMesh(), outDir, String())
# New polyline polyline = ArrayList() listOfPolylines.add(polyline) polyline.add(vertices.get(2*b)) lastVertex = vertices.get(2*b+1) polyline.add(lastVertex) #print "Group "+str(bId)+" contains "+str(listOfPolylines.size())+" polylines and "+str(listBeamId.size()+1)+" vertices" mapGroupToListOfPolylines.put(bId, listOfPolylines) for bId in bgroupMap.keySet(): listBeamId = bgroupMap.get(bId) listOfPolylines = mapGroupToListOfPolylines.get(bId) nrPoly = listOfPolylines.size() for numPoly in xrange(nrPoly): polyline = listOfPolylines.get(numPoly) if options.point_metric_file: met = DistanceMetric(options.size, options.point_metric_file) elif setAnalytic: met = RemeshMetric() else: met = ArrayList() for v in polyline: met.add(EuclidianMetric3D(options.size)) #print "Remesh polyline "+str(numPoly+1)+"/"+str(nrPoly)+" of group "+str(bId)+"/"+str(bgroupMap.size())+" "+str(polyline.size())+" vertices" result = RemeshPolyline(newMesh, polyline, met).compute() for i in xrange(result.size() - 1): newMesh.addBeam(result.get(i), result.get(i+1), bId) #print " New polyline: "+str(result.size())+" vertices" MeshWriter.writeObject3D(newMesh, outDir, "")
def clean(**kwargs): """Clean a mesh """ # Process coplanarity options coplanarity = -2.0 if kwargs['coplanarityAngle'] > 0: coplanarity = cos(kwargs['coplanarityAngle'] * pi / 180.) if kwargs['coplanarity']: coplanarity = kwargs['coplanarity'] safe_coplanarity = kwargs['safe_coplanarity'] if safe_coplanarity is None: safe_coplanarity = 0.8 safe_coplanarity = str(max(coplanarity, safe_coplanarity)) # Build background mesh try: liaison = kwargs['liaison'] except KeyError: mtb = MeshTraitsBuilder.getDefault3D() if kwargs['recordFile']: mtb.addTraceRecord() mtb.addNodeSet() mesh = Mesh(mtb) if kwargs['recordFile']: mesh.getTrace().setDisabled(True) MeshReader.readObject3D(mesh, kwargs['in_dir']) liaison = MeshLiaison.create(mesh, mtb) if kwargs['recordFile']: liaison.getMesh().getTrace().setDisabled(False) liaison.getMesh().getTrace().setLogFile(kwargs['recordFile']) liaison.getMesh().getTrace().createMesh("mesh", liaison.getMesh()) if kwargs['immutable_border']: liaison.mesh.tagFreeEdges(AbstractHalfEdge.IMMUTABLE) liaison.getMesh().buildRidges(coplanarity) if kwargs['preserveGroups']: liaison.getMesh().buildGroupBoundaries() immutable_groups = [] if kwargs['immutable_groups_file']: f = open(kwargs['immutable_groups_file']) immutable_groups = f.read().split() f.close() liaison.mesh.tagGroups(immutable_groups, AbstractHalfEdge.IMMUTABLE) if kwargs['recordFile']: cmds = [ String("assert self.m.checkNoDegeneratedTriangles()"), String("assert self.m.checkNoInvertedTriangles()"), String("assert self.m.checkVertexLinks()"), String("assert self.m.isValid()") ] liaison.getMesh().getTrace().setHooks(cmds) # Swap swapOptions = HashMap() swapOptions.put("coplanarity", str(safe_coplanarity)) swapOptions.put("minCosAfterSwap", "0.3") SwapEdge(liaison, swapOptions).compute() # Improve valence valenceOptions = HashMap() valenceOptions.put("coplanarity", str(safe_coplanarity)) valenceOptions.put("checkNormals", "false") ImproveVertexValence(liaison, valenceOptions).compute() # Smooth smoothOptions = HashMap() smoothOptions.put("iterations", str(8)) smoothOptions.put("check", "true") smoothOptions.put("boundaries", "true") smoothOptions.put("relaxation", str(0.6)) if (safe_coplanarity >= 0.0): smoothOptions.put("coplanarity", str(safe_coplanarity)) SmoothNodes3DBg(liaison, smoothOptions).compute() # Remove Degenerated rdOptions = HashMap() rdOptions.put("rho", str(kwargs['eratio'])) RemoveDegeneratedTriangles(liaison, rdOptions).compute() # Output MeshWriter.writeObject3D(liaison.getMesh(), kwargs['out_dir'], "") if kwargs['recordFile']: liaison.getMesh().getTrace().finish()