def _egi_sort_v_nbrs(egi): """ By default, the sorting should be ccw, since the circle is typically drawn ccw around the local plane's z-axis... """ xyz = dict( (key, [attr[_] for _ in 'xyz']) for key, attr in egi.vertices(True)) for vkey in egi.vertex: nbrs = egi.vertex[vkey]['nbrs'] plane = Plane(Point3d(*xyz[vkey]), Vector3d(*[axis for axis in egi.vertex[vkey]['normal']])) circle = Circle(plane, 1) p_list = [] for nbr_vkey in nbrs: boolean, parameter = ArcCurve(circle).ClosestPoint( Point3d(*xyz[nbr_vkey])) p_list.append(parameter) sorted_nbrs = [key for (param, key) in sorted(zip(p_list, nbrs))] egi.vertex[vkey]['sorted_nbrs'] = sorted_nbrs
def draw_spheres(spheres, **kwargs): """Draw spheres and optionally set individual name, color, and layer properties. Parameters ---------- spheres : list of dict A list of sphere dictionaries. Returns ------- list of GUID Notes ----- A sphere dict has the following schema: .. code-block:: python Schema({ 'pos': And(list, lambda x: len(x) == 3), 'radius': And(Or(int, float), lambda x: x > 0.0), Optional('name', default=''): str, Optional('color', default=None): And(lambda x: len(x) == 3, all(0 <= y <= 255 for y in x)), Optional('layer', default=None): str, }) """ guids = [] for s in iter(spheres): pos = s['pos'] radius = s['radius'] name = s.get('name', '') color = s.get('color') layer = s.get('layer') sphere = Sphere(Point3d(*pos), radius) guid = add_sphere(sphere) if not guid: continue obj = find_object(guid) if not obj: continue attr = obj.Attributes if color: attr.ObjectColor = FromArgb(*color) attr.ColorSource = ColorFromObject else: attr.ColorSource = ColorFromLayer if layer and find_layer_by_fullpath: index = find_layer_by_fullpath(layer, True) if index >= 0: attr.LayerIndex = index attr.Name = name attr.WireDensity = -1 obj.CommitChanges() guids.append(guid) return guids
def draw_circles(circles, **kwargs): """Draw circles and optionally set individual name, color, and layer properties. Parameters ---------- circles : list of dict A list of circle dictionaries. Returns ------- list of GUID Notes ----- A circle dict has the following schema: .. code-block:: python Schema({ 'plane': lambda x: len(x[0]) == 3 and len(x[1]) == 3, 'radius': And(Or(int, float), lambda x: x > 0), Optional('name', default=''): str, Optional('color', default=None): And(lambda x: len(x) == 3, all(0 <= y <= 255 for y in x)), Optional('layer', default=None): str }) """ guids = [] for data in iter(circles): point, normal = data['plane'] radius = data['radius'] name = data.get('name', '') color = data.get('color') layer = data.get('layer') circle = Circle(Plane(Point3d(*point), Vector3d(*normal)), radius) guid = add_circle(circle) if not guid: continue obj = find_object(guid) if not obj: continue attr = obj.Attributes if color: attr.ObjectColor = FromArgb(*color) attr.ColorSource = ColorFromObject else: attr.ColorSource = ColorFromLayer if layer and find_layer_by_fullpath: index = find_layer_by_fullpath(layer, True) if index >= 0: attr.LayerIndex = index attr.Name = name attr.WireDensity = -1 obj.CommitChanges() guids.append(guid) return guids
def xdraw_polylines(polylines): """Draw polylines. """ rg_polylines = [] for p in iter(polylines): points = p['points'] poly = Polyline([Point3d(*xyz) for xyz in points]) poly.DeleteShortSegments(TOL) rg_polylines.append(poly) return rg_polylines
def DrawForeground(self, e): """Draw the labels as text dots. Parameters ---------- e : Rhino.Display.DrawEventArgs Returns ------- None """ for i, (pos, text) in enumerate(self.labels): if self.color: color, textcolor = self.color[i] e.Display.DrawDot(Point3d(*pos), text, color, textcolor) else: e.Display.DrawDot(Point3d(*pos), text, self.default_color, self.default_textcolor)
def __init__(self): self.position = Point3d(random.randint(box.x[0], b_x), random.randint(box.y[0], b_y), random.randint(box.z[0], b_z)) self.velocity = Vector3d(random.random(), random.random(), random.random()) self.acceleration = Vector3d(0, 0, 0) self.max_speed = 3 self.max_force = 0.3 self.trail = []
def xdraw_cylinders(cylinders, cap=False, **kwargs): guids = [] for c in iter(cylinders): start = c['start'] end = c['end'] radius = c['radius'] name = c.get('name', '') color = c.get('color') layer = c.get('layer') if radius < TOL: continue base = Point3d(*start) normal = Point3d(*end) - base height = normal.Length if height < TOL: continue plane = Plane(base, normal) circle = Circle(plane, radius) cylinder = Cylinder(circle, height) brep = cylinder.ToBrep(cap, cap) if not brep: continue guid = add_brep(brep) if not guid: continue obj = find_object(guid) if not obj: continue attr = obj.Attributes if color: attr.ObjectColor = FromArgb(*color) attr.ColorSource = ColorFromObject else: attr.ColorSource = ColorFromLayer if layer and find_layer_by_fullpath: index = find_layer_by_fullpath(layer, True) if index >= 0: attr.LayerIndex = index attr.Name = name attr.WireDensity = -1 obj.CommitChanges() guids.append(guid) return guids
def DrawForeground(self, e): _conduit_mesh_edges(self.mesh, e) if self.face_colordict: for fkey in self.face_colordict: color = FromArgb(*self.face_colordict[fkey]) points = self.mesh.face_coordinates(fkey) points.append(points[0]) points = [Point3d(*pt) for pt in points] e.Display.DrawPolygon(points, color, filled=True)
def draw_labels(labels, **kwargs): """Draw labels as text dots and optionally set individual font, fontsize, name and color. Parameters ---------- labels : list of dict A list of labels dictionaries. Returns ------- list of GUID Notes ----- A label dict has the following schema: .. code-block:: python Schema({ 'pos': And(list, lambda x: len(x) == 3), 'text': And(str, len), Optional('name', default=''): str, Optional('color', default=None): (lambda x: len(x) == 3 and all(0 <= y <= 255 for y in x)), Optional('fontsize', default=10): Or(int, float), Optional('font', default="Arial Regular"): str }) """ guids = [] for label in iter(labels): pos = label['pos'] text = label['text'] name = label.get('name', '') color = label.get('color', None) size = label.get('fontsize', 10) font = label.get('font', 'Arial Regular') dot = TextDot(str(text), Point3d(*pos)) dot.FontHeight = size dot.FontFace = font guid = add_dot(dot) if not guid: continue obj = find_object(guid) if not obj: continue attr = obj.Attributes if color: attr.ObjectColor = FromArgb(*color) attr.ColorSource = ColorFromObject else: attr.ColorSource = ColorFromLayer attr.Name = name obj.CommitChanges() guids.append(guid) return guids
def OnDynamicDraw(sender, e): cp = e.CurrentPoint for vertex in vertices: xyz = diagram.vertex_coordinates(vertex) sp = Point3d(*xyz) sp_f = update_point(sp, cp) for nbr_vkey in nbr_vkeys[vertex]: nbr = diagram.vertex_coordinates(nbr_vkey) np = Point3d(*nbr) e.Display.DrawDottedLine(np, sp_f, dotted_color) e.Display.DrawLine(sp, sp_f, edge_color, 3) for pair in list(edges): pair = list(pair) u = diagram.vertex_coordinates(pair[0]) v = diagram.vertex_coordinates(pair[1]) sp = update_point(Point3d(*u), cp) ep = update_point(Point3d(*v), cp) e.Display.DrawLine(sp, ep, edge_color, 3)
def move(self): #update position based on new heading ### we now have a property in "energy" that determines how far the bird can travel (in behavioral space) each time step ### we might understand this as 'enthusiasm', or 'behavioral engagement in workplace culture' self.position = Point3d.Add(self.position, self.heading * self.energy) ### leave points behind for later analysis if the bird is feeling welcome or unwelcome if self.inclusion > .25: self.inclusiveTrail.append(self.position) else: self.exclusiveTrail.append(self.position)
def OnDynamicDraw(sender, e): cp = e.CurrentPoint translation = cp - ip for vertex in vertices: xyz = diagram.vertex_coordinates(vertex) sp = Point3d(*xyz) for nbr_vkey in nbr_vkeys[vertex]: nbr = diagram.vertex_coordinates(nbr_vkey) np = Point3d(*nbr) line = Rhino.Geometry.Line(sp, sp + translation) e.Display.DrawDottedLine(np, sp + translation, dotted_color) e.Display.DrawArrow(line, arrow_color, 15, 0) for pair in list(edges): pair = list(pair) u = diagram.vertex_coordinates(pair[0]) v = diagram.vertex_coordinates(pair[1]) sp = Point3d(*u) + translation ep = Point3d(*v) + translation e.Display.DrawLine(sp, ep, edge_color, 3)
def xdraw_breps(faces, srf=None, u=10, v=10, trim=True, tangency=True, spacing=0.1, flex=1.0, pull=1.0): """Draw polygonal faces as Breps, and optionally set individual name, color, and layer properties. """ guids = [] for f in iter(faces): points = f['points'] name = f.get('name', '') color = f.get('color') layer = f.get('layer') corners = [Point3d(*point) for point in points] pcurve = PolylineCurve(corners) geo = List[GeometryBase](1) geo.Add(pcurve) p = len(points) if p == 4: brep = Brep.CreateFromCornerPoints(Point3d(*points[0]), Point3d(*points[1]), Point3d(*points[2]), TOL) elif p == 5: brep = Brep.CreateFromCornerPoints(Point3d(*points[0]), Point3d(*points[1]), Point3d(*points[2]), Point3d(*points[3]), TOL) else: brep = Brep.CreatePatch(geo, u, v, TOL) if not brep: continue guid = add_brep(brep) if not guid: continue obj = find_object(guid) if not obj: continue attr = obj.Attributes if color: attr.ObjectColor = FromArgb(*color) attr.ColorSource = ColorFromObject else: attr.ColorSource = ColorFromLayer if layer: index = find_layer_by_fullpath(layer, True) if index >= 0: attr.LayerIndex = index attr.Name = name attr.WireDensity = -1 obj.CommitChanges() guids.append(guid) return guids
def _face_adjacency(xyz, faces, nmax=10, radius=2.0): points = [ centroid_points([xyz[index] for index in face]) for face in faces ] tree = RTree() for i, point in enumerate(points): tree.Insert(Point3d(*point), i) def callback(sender, e): data = e.Tag data.append(e.Id) closest = [] for i, point in enumerate(points): sphere = Sphere(Point3d(*point), radius) data = [] tree.Search(sphere, callback, data) closest.append(data) adjacency = {} for face, vertices in enumerate(faces): nbrs = [] found = set() nnbrs = set(closest[face]) for u, v in pairwise(vertices + vertices[0:1]): for nbr in nnbrs: if nbr == face: continue if nbr in found: continue for a, b in pairwise(faces[nbr] + faces[nbr][0:1]): if v == a and u == b: nbrs.append(nbr) found.add(nbr) break for a, b in pairwise(faces[nbr] + faces[nbr][0:1]): if u == a and v == b: nbrs.append(nbr) found.add(nbr) break adjacency[face] = nbrs return adjacency
def point_to_rhino(point): """Convert a COMPAS point to a Rhino point. Parameters ---------- point : :class:`compas.geometry.Point` Returns ------- :class:`Rhino.Geometry.Point3d` """ return Point3d(point[0], point[1], point[2])
def xdraw_cylinders(cylinders, cap=False): rg_cylinders = [] for c in iter(cylinders): start = c['start'] end = c['end'] radius = c['radius'] if radius < TOL: continue base = Point3d(*start) normal = Point3d(*end) - base height = normal.Length if height < TOL: continue plane = Plane(base, normal) circle = Circle(plane, radius) cylinder = Cylinder(circle, height) brep = cylinder.ToBrep(cap, cap) if not brep: continue rg_cylinders.append(brep) return rg_cylinders
def draw_points(points, **kwargs): """Draw points and optionally set individual name, layer, and color properties. Parameters ---------- labels : list[dict] A list of point dictionaries. See Notes, for more information about the structure of the dict. Returns ------- list[System.Guid] Notes ----- A point dict has the following schema: .. code-block:: python Schema({ 'pos': And(list, lambda x: len(x) == 3), Optional('name', default=''): str, Optional('color', default=None): (lambda x: len(x) == 3 and all(0 <= y <= 255 for y in x)), Optional('layer', default=None): str }) """ guids = [] for p in iter(points): pos = p['pos'] name = p.get('name', '') color = p.get('color') layer = p.get('layer') guid = add_point(Point3d(*pos)) if not guid: continue obj = find_object(guid) if not obj: continue attr = obj.Attributes if color: attr.ObjectColor = FromArgb(*color) attr.ColorSource = ColorFromObject else: attr.ColorSource = ColorFromLayer if layer and find_layer_by_fullpath: index = find_layer_by_fullpath(layer, True) if index >= 0: attr.LayerIndex = index attr.Name = name obj.CommitChanges() guids.append(guid) return guids
def xdraw_lines(lines, **kwargs): """Draw lines and optionally set individual name, color, arrow, layer, and width properties. """ guids = [] for l in iter(lines): sp = l['start'] ep = l['end'] name = l.get('name', '') color = l.get('color') arrow = l.get('arrow') layer = l.get('layer') width = l.get('width') guid = add_line(Point3d(*sp), Point3d(*ep)) if not guid: continue obj = find_object(guid) if not obj: continue attr = obj.Attributes if color: attr.ObjectColor = FromArgb(*color) attr.ColorSource = ColorFromObject else: attr.ColorSource = ColorFromLayer if arrow == 'end': attr.ObjectDecoration = EndArrowhead if arrow == 'start': attr.ObjectDecoration = StartArrowhead if layer and find_layer_by_fullpath: index = find_layer_by_fullpath(layer, True) if index >= 0: attr.LayerIndex = index if width: attr.PlotWeight = width attr.PlotWeightSource = PlotWeightFromObject attr.Name = name obj.CommitChanges() guids.append(guid) return guids
def trimesh_slice(mesh, planes): """Slice a mesh by a list of planes. Parameters ---------- mesh : tuple of vertices and faces The mesh to slice. planes : list of (point, normal) tuples or compas.geometry.Plane The slicing planes. Returns ------- list of arrays The points defining the slice polylines. Examples -------- >>> from compas.geometry import Sphere, Plane, Point, Vector >>> sphere = Sphere([1, 1, 1], 1) >>> sphere = sphere.to_vertices_and_faces(u=30, v=30) >>> P1 = Plane(Point(0, 0, 0), Vector(0, -1, 0)) >>> P2 = Plane(Point(0, 0, 0), Vector(0.87, -0.5, 0)) >>> planes = [P1, P2] >>> points = trimesh_slice(sphere, planes) """ # (0) see if input is already Rhino.Geometry.Mesh M = Rhino.Geometry.Mesh() if not isinstance(mesh, Rhino.Geometry.Mesh): for x, y, z in mesh[0]: M.Vertices.Add(x, y, z) for face in mesh[1]: M.Faces.AddFace(*face) else: M = mesh # (1) parse to Rhino.Geometry.Plane P = [] for plane in planes: point = Point3d(plane[0][0], plane[0][1], plane[0][2]) normal = Vector3d(plane[1][0], plane[1][1], plane[1][2]) P.append(Plane(point, normal)) # (2) Slice polylines = MeshPlane(M, P) # (3) Return points in a list of arrays polyline_pts = [] for polyline in polylines: pts = [] for i in range(polyline.Count): pts.append([polyline.X[i], polyline.Y[i], polyline.Z[i]]) polyline_pts.append(pts) return polyline_pts
def contourBrepInZ(brep, stepSize): # get the upper and lower limits bbox = brep.GetBoundingBox(True) zMin, zMax = bbox.Min.Z, bbox.Max.Z zRange = zMax-zMin vect = Vector3d(0.0,0.0,1.0) # the next line is dense planes = [Plane(Point3d(0.0, 0.0, z), vect) for z in RangeTools.drange(zMin,zMax, 0.5)] resultList = [] for plane in planes: curves = brep.CreateContourCurves(brep, plane) resultList.append(curves) return resultList
def DrawForeground(self, e): _conduit_volmesh_edges(self.volmesh, e) if self.face_colordict: for fkey in self.face_colordict: color = FromArgb(*self.face_colordict[fkey]) f_vkeys = self.volmesh.halfface_vertices(fkey) points = [ self.volmesh.vertex_coordinates(vkey) for vkey in f_vkeys ] points.append(points[0]) points = [Point3d(*pt) for pt in points] e.Display.DrawPolygon(points, color, filled=True)
def DrawForeground(self, e): p1 = self.mouse.p1 p2 = self.mouse.p2 v12 = subtract_vectors(p2, p1) l12 = length_vector(v12) hfkeys = self.volmesh.faces() if self.hfkeys: hfkeys = self.hfkeys for hfkey in hfkeys: p0 = self.volmesh.halfface_center(hfkey) v01 = subtract_vectors(p1, p0) v02 = subtract_vectors(p2, p0) l = length_vector(cross_vectors(v01, v02)) if l12 == 0.0 or (l / l12) < self.tol: face_coordinates = self.volmesh.halfface_coordinates(hfkey) face_coordinates.append(face_coordinates[0]) polygon_xyz = [Point3d(*xyz) for xyz in face_coordinates] e.Display.DrawPolyline(polygon_xyz, self.edgecolor, 6) if self.dependents: d_hfkeys = self.volmesh.volmesh_edge_dependents_all(hfkey) for d_hfkey in d_hfkeys: face_coordinates = self.volmesh.halfface_coordinates( d_hfkey) face_coordinates.append(face_coordinates[0]) polygon_xyz = [ Point3d(*xyz) for xyz in face_coordinates ] e.Display.DrawPolyline(polygon_xyz, self.edgecolor, 2) break
def xdraw_geodesics(geodesics, **kwargs): """Draw geodesic lines on specified surfaces, and optionally set individual name, color, arrow, and layer properties. """ guids = [] for g in iter(geodesics): sp = g['start'] ep = g['end'] srf = g['srf'] name = g.get('name', '') color = g.get('color') arrow = g.get('arrow') layer = g.get('layer') # replace this by a proper rhinocommon call guid = rs.ShortPath(srf, Point3d(*sp), Point3d(*ep)) if not guid: continue obj = find_object(guid) if not obj: continue attr = obj.Attributes if color: attr.ObjectColor = FromArgb(*color) attr.ColorSource = ColorFromObject else: attr.ColorSource = ColorFromLayer if arrow == 'end': attr.ObjectDecoration = EndArrowhead if arrow == 'start': attr.ObjectDecoration = StartArrowhead if layer and find_layer_by_fullpath: index = find_layer_by_fullpath(layer, True) if index >= 0: attr.LayerIndex = index attr.Name = name obj.CommitChanges() guids.append(guid) return guids
def DrawForeground(self, e): """Draw the points. Parameters ---------- e : Rhino.Display.DrawEventArgs Returns ------- None """ for xyz, size, color in zip(self.points, self.size, self.color): e.Display.DrawPoint(Point3d(*xyz), Simple, size, color)
def OnDynamicDraw(sender, e): cp = e.CurrentPoint plane = (cp, normal) line = (center, add_vectors(center, normal)) it = intersection_line_plane(line, plane) translation = subtract_vectors(it, center) dot = dot_vectors(normal, translation) dot = dot / abs(dot) dist = distance_point_point(center, it) * dot for hfkey in hfkeys: hf_center = volmesh.halfface_center(hfkey) hf_normal = volmesh.halfface_oriented_normal(hfkey) ep = add_vectors(hf_center, scale_vector(hf_normal, dist)) e.Display.DrawDottedLine(Point3d(*hf_center), Point3d(*ep), feedback_color) e.Display.DrawPoint(Point3d(*ep), 0, 4, black) for vkey in volmesh.halfface_vertices(hfkey): sp = volmesh.vertex_coordinates(vkey) e.Display.DrawLine(Point3d(*sp), Point3d(*ep), black, 2)
def DrawForeground(self, e): draw_dot = e.Display.DrawDot draw_arrows = e.Display.DrawArrows a = self.mouse.p1 b = self.mouse.p2 ab = subtract_vectors(b, a) Lab = length_vector(ab) if not Lab: return for index, vertex in enumerate(self.vertex_xyz): c = self.vertex_xyz[vertex] D = length_vector( cross_vectors(subtract_vectors(a, c), subtract_vectors(b, c))) if D / Lab < self.tol: point = Point3d(*c) draw_dot(point, str(index), self.dotcolor, self.textcolor) lines = List[Line](len(self.vertex_nbr[vertex])) for u, v in self.vertex_nbr[vertex]: lines.Add( Line(Point3d(*self.vertex_xyz[u]), Point3d(*self.vertex_xyz[v]))) draw_arrows(lines, self.linecolor) break
def RunCommand(): # select a surface srfid = rs.GetObject("select serface", rs.filter.surface | rs.filter.polysurface) if not srfid: return # get the brep brep = rs.coercebrep(srfid) if not brep: return x = rs.GetReal("value of x", 0) y = rs.GetReal("value of y", 0) pts = [(abs(point.Z), point.Z) for point in Intersect.Intersection.ProjectPointsToBreps( [brep], [Point3d(x, y, 0)], Vector3d( 0, 0, 1), doc.ModelAbsoluteTolerance)] pts.sort(reverse=True) if pts == []: print "no Z for given X, Y" else: rs.AddPoint(Point3d(x, y, pts[0][1]))
def DrawForeground(self, e): p1 = self.mouse.p1 p2 = self.mouse.p2 v12 = subtract_vectors(p2, p1) l12 = length_vector(v12) for index, (key, attr) in enumerate(self.mesh.vertices(True)): p0 = attr['x'], attr['y'], attr['z'] text = str(index) v01 = subtract_vectors(p1, p0) v02 = subtract_vectors(p2, p0) l = length_vector(cross_vectors(v01, v02)) # noqa: E741 if l12 == 0.0 or (l / l12) < self.tol: point = Point3d(*p0) e.Display.DrawDot(point, text, self.dotcolor, self.textcolor) break
def separation(self, boids, radius=3, angle=10): neighbors = self.get_neighbors(boids, radius, angle) pox = 0 poy = 0 poz = 0 if len(neighbors) > 0: n_neighbors = len(neighbors) for i in neighbors: pox += i.position.X poy += i.position.Y poz += i.position.Z center = Point3d(pox / n_neighbors, poy / n_neighbors, poz / n_neighbors) return (center - self.position) * -1 else: return Vector3d(0, 0, 0)
def xdraw_pipes(pipes, cap=2, fit=1.0): abs_tol = TOL ang_tol = sc.doc.ModelAngleToleranceRadians for p in pipes: points = p['points'] radius = p['radius'] params = [0.0, 1.0] cap = ToObject(PipeCapMode, cap) if type(radius) in (int, float): radius = [radius] * 2 radius = [float(r) for r in radius] rail = Curve.CreateControlPointCurve([Point3d(*xyz) for xyz in points]) breps = Brep.CreatePipe(rail, params, radius, 1, cap, fit, abs_tol, ang_tol) for brep in breps: yield brep