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 remesh_beams(liaison, size, rho, immutable_groups, point_metric_file=None): # immutable groups # wire metric metric = None if point_metric_file is not None: metric_type = check_metric_type(point_metric_file) if metric_type == "singular": if rho > 1.0: # mixed metric metric = SingularMetric(size, point_metric_file, rho, True) else: # analytic metric metric = SingularMetric(size, point_metric_file) else: metric = DistanceMetric(size, point_metric_file) polylines = PolylineFactory(liaison.mesh, 135.0, size * 0.2) liaison.mesh.resetBeams() for entry in polylines.entrySet(): groupId = entry.key for polyline in entry.value: if point_metric_file is None: metric = ArrayList() for v in polyline: metric.add(EuclidianMetric3D(size)) if liaison.mesh.getGroupName(groupId) in immutable_groups: result = polyline else: result = RemeshPolyline(liaison.mesh, polyline, metric).compute() for i in xrange(result.size() - 1): liaison.mesh.addBeam(result.get(i), result.get(i + 1), groupId) # redefine liaison to remove orphan nodes mesh = liaison.getMesh() mtb = MeshTraitsBuilder.getDefault3D() mtb.addNodeSet() liaison = MeshLiaison.create(mesh, mtb) return liaison
parser.print_usage() sys.exit(1) xmlDir = args[0] outDir = args[1] mtb = MeshTraitsBuilder.getDefault3D() if options.recordFile: mtb.addTraceRecord() mtb.addNodeSet() mesh = Mesh(mtb) if options.recordFile: mesh.getTrace().setDisabled(True) MeshReader.readObject3D(mesh, xmlDir) liaison = MeshLiaison.create(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.immutable_border: liaison.mesh.tagFreeEdges(AbstractHalfEdge.IMMUTABLE) if options.coplanarity: liaison.getMesh().buildRidges(options.coplanarity) if options.preserveGroups: liaison.getMesh().buildGroupBoundaries() 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)
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())
if options.freeEdgeTol: opts.put("freeEdgeTol", str(options.freeEdgeTol)) if options.maxlength: opts.put("maxlength", str(options.maxlength)) mtb = MeshTraitsBuilder.getDefault3D() if options.recordFile: mtb.addNodeSet() 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()
parser.print_usage() sys.exit(1) xmlDir = args[0] outDir = args[1] mtb = MeshTraitsBuilder.getDefault3D() if options.recordFile: mtb.addTraceRecord() mtb.addNodeSet() mesh = Mesh(mtb) if options.recordFile: mesh.getTrace().setDisabled(True) MeshReader.readObject3D(mesh, xmlDir) 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.immutable_border: liaison.mesh.tagFreeEdges(AbstractHalfEdge.IMMUTABLE) liaison.getMesh().buildRidges(0.9) if options.immutable_border_group: liaison.mesh.tagGroupBoundaries(AbstractHalfEdge.IMMUTABLE) else: if options.preserveGroups: liaison.getMesh().buildGroupBoundaries() #0 writeVTK(liaison)
dest="maxtriangles", help="stop splitting when mesh contains NUMBER triangles") (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() mesh = Mesh(mtb) MeshReader.readObject3D(mesh, xmlDir) liaison = MeshLiaison(mesh, mtb) if options.coplanarity: liaison.getMesh().buildRidges(options.coplanarity) opts = HashMap() if options.size: opts.put("size", str(options.size)) if options.coplanarity: opts.put("coplanarity", str(options.coplanarity)) if options.maxtriangles: opts.put("maxtriangles", str(options.maxtriangles)) class SplitDebug(SplitEdge): cnt = 0 liaison = None
help="Tag free edges as immutable") parser.add_option("-i", "--no-expect-insert", action="store_true", dest="no_expect_insert", help="Relax swapping conditions when no further point insertion are expected") (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) liaison = MeshLiaison(mesh) 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("coplanarity", str(options.coplanarity)) if options.min_quality_factor: opts.put("minQualityFactor", str(options.min_quality_factor)) if options.no_expect_insert: opts.put("expectInsert", "false") sm = SwapEdge(liaison, opts) sm.setProgressBarStatus(10000)
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, "")
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, "")
parser.print_usage() sys.exit(1) xmlDir = args[0] outDir = args[1] mtb = MeshTraitsBuilder.getDefault3D() if options.recordFile: mtb.addTraceRecord() mtb.addNodeSet() mesh = Mesh(mtb) if options.recordFile: mesh.getTrace().setDisabled(True) MeshReader.readObject3D(mesh, xmlDir) 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.immutable_border: liaison.mesh.tagFreeEdges(AbstractHalfEdge.IMMUTABLE) if options.coplanarity: liaison.getMesh().buildRidges(options.coplanarity) if options.preserveGroups: liaison.getMesh().buildGroupBoundaries() opts = HashMap() setAnalytic = False if options.size: opts.put("size", str(options.size))
action="store", type="int", dest="maxtriangles", help="stop splitting when mesh contains NUMBER triangles") (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() mesh = Mesh(mtb) MeshReader.readObject3D(mesh, xmlDir) liaison = MeshLiaison(mesh, mtb) if options.coplanarity: liaison.getMesh().buildRidges(options.coplanarity) opts = HashMap() if options.size: opts.put("size", str(options.size)) if options.coplanarity: opts.put("coplanarity", str(options.coplanarity)) if options.maxtriangles: opts.put("maxtriangles", str(options.maxtriangles)) class SplitDebug(SplitEdge): cnt = 0 liaison = None ridges = False
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()
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] mtb = MeshTraitsBuilder.getDefault3D() mesh = Mesh(mtb) MeshReader.readObject3D(mesh, xmlDir) liaison = MeshLiaison(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)) ImproveEdgeConnectivity(liaison, opts).compute() MeshWriter.writeObject3D(liaison.getMesh(), outDir, String())
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()