示例#1
0
def decomposition_skeleton(srf_guid, decomposition):
    # output remapped topological skeleton/medial axis
    return [
        RhinoSurface(srf_guid).polyline_uv_to_xyz(
            [xyz[:2] for xyz in polyline])
        for polyline in decomposition.branches()
    ]
示例#2
0
def customized_smoothing_constraints(mesh, constraints):
    """Add custom point, curve and surface constraints to the vertices of a mesh to smooth.

	Parameters
	----------
	mesh : Mesh
		The mesh to apply the constraints to for smoothing.
	constraints : dict
		A dictionary of mesh constraints for smoothing as vertex keys pointing to point, curve or surface objects.

	Returns
	-------
	constraints : dict
		The updated dictionary of mesh constraints for smoothing as vertex keys pointing to point, curve or surface objects.

	"""

    while True:

        guids = display_smoothing_constraints(mesh, constraints)
        vkeys = mesh_select_vertices(mesh)
        if len(vkeys) == 2 and rs.GetString(
                'get all polyedge?', strings=['True', 'False']) == 'True':
            u, v = vkeys
            vkeys = mesh.polyedge(u, v)

        if vkeys is None:
            break

        constraint = rs.GetString(
            'edit smoothing constraints?',
            strings=['point', 'curve', 'surface', 'exit'])

        rs.DeleteObjects(guids)

        if constraint is None or constraint == 'exit':
            break

        elif constraint == 'point':
            point = RhinoPoint.from_selection()
            constraints.update({vkey: point.guid for vkey in vkeys})

        elif constraint == 'curve':
            curve = RhinoCurve.from_selection()
            constraints.update({vkey: curve.guid for vkey in vkeys})

        elif constraint == 'surface':
            surface = RhinoSurface.from_selection()
            constraints.update({vkey: surface.guid for vkey in vkeys})

    return constraints
示例#3
0
    def callback(k, args):

        mesh, constraints = args

        for vkey, constraint in constraints.items():
            if rs.ObjectType(constraint) == 1:
                x, y, z = RhinoPoint.from_guid(constraint).xyz
            elif rs.ObjectType(constraint) == 4:
                x, y, z = RhinoCurve.from_guid(constraint).closest_point(
                    mesh.vertex_coordinates(vkey))
            elif rs.ObjectType(constraint) == 8:
                x, y, z = RhinoSurface.from_guid(constraint).closest_point(
                    mesh.vertex_coordinates(vkey))
            elif rs.ObjectType(constraint) == 32:
                x, y, z = RhinoMesh.from_guid(constraint).closest_point(
                    mesh.vertex_coordinates(vkey))
            else:
                continue

            mesh.vertex[vkey]['x'] = x
            mesh.vertex[vkey]['y'] = y
            mesh.vertex[vkey]['z'] = z
示例#4
0
def surface_discrete_mapping(srf_guid,
                             discretisation,
                             minimum_discretisation=5,
                             crv_guids=[],
                             pt_guids=[]):
    """Map the boundaries of a Rhino NURBS surface to planar poylines dicretised within some discretisation using the surface UV parameterisation.
	Curve and point feautres on the surface can be included.

	Parameters
	----------
	srf_guid : guid
		A surface guid.
	crv_guids : list
		List of guids of curves on the surface.
	pt_guids : list
		List of guids of points on the surface.
	discretisation : float
		The discretisation of the surface boundaries.
	minimum_discretisation : int
		The minimum discretisation of the surface boundaries.

	Returns
	-------
	tuple
		Tuple of the mapped objects: outer boundary, inner boundaries, polyline_features, point_features.

	"""

    srf = RhinoSurface(srf_guid)

    # a boundary may be made of multiple boundary components and therefore checking for closeness and joining are necessary
    mapped_borders = []

    for i in [1, 2]:
        mapped_border = []

        for border in srf.borders(type=i):
            border = RhinoCurve(border)
            points = [
                list(srf.point_xyz_to_uv(pt)) + [0.0] for pt in border.divide(
                    max(
                        int(border.length() / discretisation) +
                        1, minimum_discretisation))
            ]

            if border.is_closed():
                points.append(points[0])

            mapped_border.append(points)
            rs.DeleteObject(border.guid)
        mapped_borders.append(mapped_border)

    outer_boundaries, inner_boundaries = [
        network_polylines(
            Network.from_lines([(u, v) for border in mapped_borders[i]
                                for u, v in pairwise(border)]))
        for i in [0, 1]
    ]

    # mapping of the curve features on the surface
    mapped_curves = []

    for crv_guid in crv_guids:

        curve = RhinoCurve(crv_guid)
        points = [
            list(srf.point_xyz_to_uv(pt)) + [0.0] for pt in curve.divide(
                max(
                    int(curve.length() / discretisation) +
                    1, minimum_discretisation))
        ]

        if curve.is_closed():
            points.append(points[0])

        mapped_curves.append(points)

    polyline_features = network_polylines(
        Network.from_lines([(u, v) for curve in mapped_curves
                            for u, v in pairwise(curve)]))

    # mapping of the point features onthe surface
    point_features = [
        list(srf.point_xyz_to_uv(rs.PointCoordinates(pt_guid))) + [0.0]
        for pt_guid in pt_guids
    ]

    return outer_boundaries[
        0], inner_boundaries, polyline_features, point_features
    srf_guid,
    float(triangulation_precision),
    crv_guids=crv_guids,
    pt_guids=pt_guids)
coarse_quad_mesh = decomposition_mesh(srf_guid, decomposition, point_features)

# density
print 'densification...'
coarse_quad_mesh.collect_strips()
coarse_quad_mesh.set_strips_density(1)
coarse_quad_mesh.set_strips_density_target(float(density_target))
coarse_quad_mesh.densification()

# smoothing
print 'smoothing...'
constraints = automated_smoothing_surface_constraints(
    coarse_quad_mesh.get_quad_mesh(), RhinoSurface.from_guid(srf_guid))
constraints.update(
    automated_smoothing_constraints(coarse_quad_mesh.get_quad_mesh(),
                                    pt_guids))
constrained_smoothing(coarse_quad_mesh.get_quad_mesh(),
                      kmax=int(kmax),
                      damping=float(damping),
                      constraints=constraints,
                      algorithm='area')
for obj in set(constraints.values()):
    if rs.ObjectType(obj) != 8:
        rs.DeleteObject(obj)

rs.EnableRedraw(False)
MeshArtist(coarse_quad_mesh.get_quad_mesh()).draw_mesh()
示例#6
0
def surface_decomposition(srf_guid,
                          precision,
                          crv_guids=[],
                          pt_guids=[],
                          output_delaunay=False,
                          output_skeleton=True,
                          output_decomposition=False,
                          output_mesh=True,
                          output_polysurface=False,
                          src='numpy_rpc'):
    """Generate the topological skeleton/medial axis of a surface based on a Delaunay triangulation, after mapping and before remapping.

	Parameters
	----------
	srf_guid : guid
		A Rhino surface guid.
	precision : float
		A discretisation precision.
	crv_guids : list
		A list of Rhino curve guids.
	pt_guids : list
		A list of Rhino points guids.
	output_delaunay : bool
		Output the Delaunay mesh or not.
		Default is False.
	output_skeleton : bool
		Output the skeleton polylines or not.
		Default is True.
	output_decomposition : bool
		Output the decomposition polylines or not.
		Default is True.
	output_mesh : bool
		Output the coarse quad mesh or not.
		Default is True.
	output_polysurface : bool
		Output the polysurface or not.
		Default is False.
	src : str
		Source of Delaunay triangulation algorithm.

	Returns
	-------
	list
		The requested outputs.

	References
	----------
	.. [1] Harry Blum. 1967. *A transformation for extracting new descriptors of shape*.
		   Models for Perception of Speech and Visual Forms, pages 362--380.
		   Available at http://pageperso.lif.univ-mrs.fr/~edouard.thiel/rech/1967-blum.pdf.
	.. [2] Punam K. Saha, Gunilla Borgefors, and Gabriella Sanniti di Baja. 2016. *A survey on skeletonization algorithms and their applications*.
		   Pattern Recognition Letters, volume 76, pages 3--12.
		   Available at https://www.sciencedirect.com/science/article/abs/pii/S0167865515001233.
	.. [3] Oval et al. 2019. *Feature-based topology finding of patterns for shell structures*.
		   Accepted in Automation in Construction.

	"""

    # mapping NURBS surface to planar polyline borders
    outer_boundary, inner_boundaries, polyline_features, point_features = surface_discrete_mapping(
        srf_guid, precision, crv_guids=crv_guids, pt_guids=pt_guids)

    # Delaunay triangulation of the palnar polyline borders
    decomposition = boundary_triangulation(outer_boundary,
                                           inner_boundaries,
                                           polyline_features,
                                           point_features,
                                           cls=Decomposition,
                                           src=src)

    outputs = []

    # output remapped Delaunay mesh
    if output_delaunay:
        outputs.append(RhinoSurface(srf_guid).mesh_uv_to_xyz(decomposition))

    # output remapped topological skeleton/medial axis
    if output_skeleton:
        outputs.append([
            RhinoSurface(srf_guid).polyline_uv_to_xyz(
                [xyz[:2] for xyz in polyline])
            for polyline in decomposition.branches()
        ])

    if output_decomposition:
        outputs.append([
            RhinoSurface(srf_guid).polyline_uv_to_xyz(
                [xyz[:2] for xyz in polyline])
            for polyline in decomposition.decomposition_polylines()
        ])

    # output decomposition coarse quad mesh
    if output_mesh:
        mesh = decomposition.decomposition_mesh(point_features)
        RhinoSurface(srf_guid).mesh_uv_to_xyz(mesh)
        outputs.append(mesh)

    # output decomposition surface
    if output_polysurface:
        mesh = decomposition.decomposition_mesh()
        nurbs_curves = {
            (geometric_key(polyline[i]), geometric_key(polyline[-i - 1])):
            rs.AddInterpCrvOnSrfUV(srf_guid, [pt[:2] for pt in polyline])
            for polyline in decomposition.decomposition_polylines()
            for i in [0, -1]
        }
        outputs.append(
            rs.JoinSurfaces([
                rs.AddEdgeSrf([
                    nurbs_curves[(geometric_key(mesh.vertex_coordinates(u)),
                                  geometric_key(mesh.vertex_coordinates(v)))]
                    for u, v in mesh.face_halfedges(fkey)
                ]) for fkey in mesh.faces()
            ],
                            delete_input=True))
        rs.DeleteObjects(list(nurbs_curves.values()))

    return outputs
示例#7
0
def editing_geometry_smoothing(coarse_pseudo_quad_mesh):
    """Edit the geometry of a pattern with smoothing.

    Parameters
    ----------
    coarse_pseudo_quad_mesh : CoarsePseudoQuadMesh
            The pattern to edit.

    """

    mesh_to_smooth = rs.GetString('mesh to smooth?',
                                  strings=[
                                      'coarse_pseudo_quad_mesh',
                                      'pseudo_quad_mesh', 'polygonal_mesh'
                                  ])
    if mesh_to_smooth == 'coarse_pseudo_quad_mesh':
        mesh = coarse_pseudo_quad_mesh
    elif mesh_to_smooth == 'pseudo_quad_mesh':
        mesh = coarse_pseudo_quad_mesh.get_quad_mesh
    elif mesh_to_smooth == 'polygonal_mesh':
        mesh = coarse_pseudo_quad_mesh.get_polygonal_mesh()
    else:
        return 0

    settings = {'iterations': 50, 'damping': .5, 'constraints': {}}

    while True:

        rs.EnableRedraw(False)
        artist = rhino_artist.MeshArtist(mesh)
        guid = artist.draw_mesh()
        rs.EnableRedraw(True)

        operation = rs.GetString(
            'edit smoothing settings?',
            strings=['smooth', 'iterations', 'damping', 'constraints', 'exit'])

        if operation is None or operation == 'exit':
            if type(guid) == list:
                rs.DeleteObjects(guid)
            else:
                rs.DeleteObject(guid)
            break

        elif operation == 'iterations':
            settings[operation] = rs.GetInteger('iterations',
                                                number=settings[operation],
                                                minimum=0)

        elif operation == 'damping':
            settings[operation] = rs.GetReal('damping',
                                             number=settings[operation],
                                             minimum=0.,
                                             maximum=1.)

        elif operation == 'constraints':
            count = 100
            while count:
                count -= 1
                guids = display_smoothing_constraints(mesh,
                                                      settings[operation])
                constraint_type = rs.GetString('type of constraints?',
                                               strings=[
                                                   'automated_from_surface',
                                                   'automated_from_objects',
                                                   'customised', 'reset',
                                                   'exit'
                                               ])
                rs.DeleteObjects(guids)
                if constraint_type == 'automated_from_surface':
                    settings[
                        operation] = automated_smoothing_surface_constraints(
                            mesh,
                            RhinoSurface(
                                rs.GetObject('surface constraints', filter=8)))
                elif constraint_type == 'automated_from_objects':
                    object_constraints = rs.GetObjects('object constraints')
                    point_constraints = [
                        obj for obj in object_constraints
                        if rs.ObjectType(obj) == 1
                    ]
                    curve_constraints = [
                        obj for obj in object_constraints
                        if rs.ObjectType(obj) == 4
                    ]
                    surface_constraint = [
                        obj for obj in object_constraints
                        if rs.ObjectType(obj) == 8
                    ]
                    if len(surface_constraint) > 1:
                        print(
                            'More than one surface constraint! Only the first one is taken into account.'
                        )
                    if len(surface_constraint) == 0:
                        surface_constraint = None
                    else:
                        surface_constraint = surface_constraint[0]
                    settings[operation] = automated_smoothing_constraints(
                        mesh, point_constraints, curve_constraints,
                        surface_constraint)
                elif constraint_type == 'customised':
                    settings[operation] = customized_smoothing_constraints(
                        mesh, settings[operation])
                elif constraint_type == 'reset':
                    artist = rhino_artist.MeshArtist(mesh, layer='mesh_artist')
                    artist.clear_layer()
                    artist.draw_vertices()
                    artist.redraw()
                    vkeys = rhino_helper.mesh_select_vertices(
                        mesh, message='vertices')
                    if vkeys is None:
                        vkeys = list(mesh.vertices())
                    artist.clear_layer()
                    artist.redraw()
                    rs.DeleteLayer('mesh_artist')
                    for vkey in vkeys:
                        if vkey in settings[operation]:
                            del settings[operation][vkey]
                else:
                    break

        elif operation == 'smooth':
            constrained_smoothing(mesh,
                                  kmax=settings['iterations'],
                                  damping=settings['damping'],
                                  constraints=settings['constraints'],
                                  algorithm='area')

        if type(guid) == list:
            rs.DeleteObjects(guid)
        else:
            rs.DeleteObject(guid)

    if mesh_to_smooth == 'coarse_pseudo_quad_mesh':
        coarse_pseudo_quad_mesh = mesh
    elif mesh_to_smooth == 'pseudo_quad_mesh':
        coarse_pseudo_quad_mesh.set_quad_mesh(mesh)
        coarse_pseudo_quad_mesh.set_polygonal_mesh(mesh.copy())
    elif mesh_to_smooth == 'polygonal_mesh':
        coarse_pseudo_quad_mesh.set_polygonal_mesh(mesh)
示例#8
0
from compas_pattern.algorithms.relaxation.relaxation import constrained_smoothing
from compas_rhino.artists import MeshArtist

guid = rs.GetObject('get mesh', filter=32)
srf_guid = rs.GetObject('get surface', filter=8)
crv_guids = rs.GetObjects('get curves', filter=4)
pt_guids = rs.GetObjects('get points', filter=1)
rs.EnableRedraw(False)
vertices = rs.MeshVertices(guid)
faces = [list(face) for face in rs.MeshFaceVertices(guid)]

mesh = Mesh.from_vertices_and_faces(vertices, faces)

if srf_guid is not None:
    constraints = automated_smoothing_surface_constraints(
        mesh, RhinoSurface(srf_guid))
else:
    constraints = {}
if crv_guids is not None:
    for vkey in mesh.vertices():
        if not mesh.is_vertex_on_boundary(vkey):
            for crv_guid in crv_guids:
                if rs.IsPointOnCurve(crv_guid, mesh.vertex_coordinates(vkey)):
                    constraints[vkey] = crv_guid
                    break

constraints.update(automated_smoothing_constraints(mesh, pt_guids))

kmax = rs.GetInteger('number of smoothing iterations?', 20, 0, 100)
damping = rs.GetReal('value of smoothing damping?', 0.5, 0, 1)
示例#9
0
def decomposition_mesh(srf_guid, decomposition, point_features):
    # output decomposition coarse quad mesh
    mesh = decomposition.decomposition_mesh(point_features)
    RhinoSurface.from_guid(srf_guid).mesh_uv_to_xyz(mesh)
    return mesh
示例#10
0
def decomposition_curves(srf_guid, decomposition):
    return [
        RhinoSurface(srf_guid).polyline_uv_to_xyz(
            [xyz[:2] for xyz in polyline])
        for polyline in decomposition.decomposition_polylines()
    ]
示例#11
0
def decomposition_delaunay(srf_guid, decomposition):
    # output remapped Delaunay mesh
    return RhinoSurface(srf_guid).mesh_uv_to_xyz(decomposition)
示例#12
0
# topology
print 'decomposition...'
coarse_quad_mesh = surface_decomposition(srf_guid,
                                         float(triangulation_precision),
                                         crv_guids=crv_guids,
                                         pt_guids=pt_guids,
                                         output_delaunay=False,
                                         output_skeleton=False,
                                         output_mesh=True,
                                         output_polysurface=False)[0]

# density
print 'densification...'
coarse_quad_mesh.init_strip_density()
coarse_quad_mesh.set_strips_density_target(float(density_target))
coarse_quad_mesh.densification()

# smoothing
print 'smoothing...'
constraints = automated_smoothing_surface_constraints(
    coarse_quad_mesh.quad_mesh, RhinoSurface(srf_guid))
constraints.update(
    automated_smoothing_constraints(coarse_quad_mesh.quad_mesh, pt_guids))
constrained_smoothing(coarse_quad_mesh.quad_mesh,
                      kmax=int(kmax),
                      damping=float(damping),
                      constraints=constraints,
                      algorithm='area')

rs.EnableRedraw(False)
draw_mesh(coarse_quad_mesh.quad_mesh)