Skip to content

Instantly share code, notes, and snippets.

@Farfarer
Created November 16, 2016 17:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Farfarer/c42ebd249602542a7369b4fd205f4fb5 to your computer and use it in GitHub Desktop.
Save Farfarer/c42ebd249602542a7369b4fd205f4fb5 to your computer and use it in GitHub Desktop.
Expands current polygon selection by material ID.
# Run with `ffr.expandByMat`, it will expand the current polygon selection by the material ID of the current polygon selection.
#
# An optional argument, `materialID` will expand only by a given material ID, e.g.
# `ffr.expandByMat "Default"`
#!/usr/bin/env python
import lx
import lxu.command
import lxifc
class PolysConnectedByMat (lxifc.Visitor):
def __init__ (self, polygon, edge, mark_mode_valid, materialID=None):
self.polygon = polygon
self.edge = edge
self.mark_mode_valid = mark_mode_valid
self.polygonIDs = set ()
self.tag = lx.object.StringTag ()
self.tag.set (self.polygon)
self.materialID = materialID
def reset (self):
self.polygonIDs = set ()
def getPolyIDs (self):
return self.polygonIDs
def vis_Evaluate (self):
inner_list = set ()
outer_list = set ()
this_polygon_ID = self.polygon.ID ()
if self.materialID is None:
materialID = self.tag.Get (lx.symbol.i_PTAG_MATR)
else:
materialID = self.materialID
if this_polygon_ID not in outer_list:
outer_list.add (this_polygon_ID)
while len(outer_list) > 0:
polygon_ID = outer_list.pop ()
self.polygon.Select (polygon_ID)
inner_list.add (polygon_ID)
num_points = self.polygon.VertexCount ()
polygon_points = [self.polygon.VertexByIndex (p) for p in xrange (num_points)]
for p in xrange (num_points):
self.edge.SelectEndpoints (polygon_points[p], polygon_points[(p+1)%num_points])
if self.edge.test ():
for e in xrange (self.edge.PolygonCount ()):
edge_polygon_ID = self.edge.PolygonByIndex (e)
if edge_polygon_ID != polygon_ID:
if edge_polygon_ID not in outer_list and edge_polygon_ID not in inner_list:
self.polygon.Select (edge_polygon_ID)
if self.polygon.TestMarks (self.mark_mode_valid) and (self.tag.Get (lx.symbol.i_PTAG_MATR) == materialID):
outer_list.add (edge_polygon_ID)
self.polygonIDs.update (inner_list)
class ExpandByMaterial_Cmd(lxu.command.BasicCommand):
def __init__(self):
lxu.command.BasicCommand.__init__ (self)
self.dyna_Add ('materialID', lx.symbol.sTYPE_STRING)
self.basic_SetFlags (0, lx.symbol.fCMDARG_OPTIONAL)
def cmd_Interact(self):
# Stop modo complaining.
pass
def cmd_UserName(self):
return 'Expand Selection by Material'
def cmd_Desc(self):
return 'Expands the current polygon selection to neighbouring polygons sharing the same material tag as the current selection.'
def cmd_Tooltip(self):
return 'Expands the current polygon selection to neighbouring polygons sharing the same material tag as the current selection.'
def cmd_Help(self):
return 'http://www.farfarer.com/'
def basic_ButtonName(self):
return 'Expand Selection by Material'
def cmd_Flags(self):
return lx.symbol.fCMD_UNDO
def basic_Enable(self, msg):
return True
def basic_Execute(self, msg, flags):
layer_svc = lx.service.Layer ()
layer_scan = lx.object.LayerScan (layer_svc.ScanAllocate (lx.symbol.f_LAYERSCAN_ACTIVE | lx.symbol.f_LAYERSCAN_MARKPOLYS))
if not layer_scan.test ():
return
materialID = self.dyna_String (0, None)
sel_svc = lx.service.Selection ()
polygon_pkts = []
# Sort out mark modes we'll need.
mesh_svc = lx.service.Mesh()
mark_mode_selected = mesh_svc.ModeCompose (lx.symbol.sMARK_SELECT, None)
mark_mode_valid = mesh_svc.ModeCompose (None, 'hide lock')
for n in xrange (layer_scan.Count ()):
mesh = lx.object.Mesh (layer_scan.MeshBase (n))
if not mesh.test ():
continue
polygon_count = mesh.PolygonCount ()
if polygon_count == 0: # Quick out if there are no polys in this layer.
continue
polygon = lx.object.Polygon (mesh.PolygonAccessor ())
if not polygon.test ():
continue
edge = lx.object.Edge (mesh.EdgeAccessor ())
if not edge.test ():
continue
visitor = PolysConnectedByMat (polygon, edge, mark_mode_valid, materialID)
polygon.Enumerate (mark_mode_selected, visitor, 0)
sel_type_polygon = sel_svc.LookupType (lx.symbol.sSELTYP_POLYGON)
sel_svc.Drop (sel_type_polygon)
poly_pkt_trans = lx.object.PolygonPacketTranslation (sel_svc.Allocate (lx.symbol.sSELTYP_POLYGON))
sel_svc.StartBatch ()
for polygonID in visitor.getPolyIDs ():
sel_svc.Select (sel_type_polygon, poly_pkt_trans.Packet (polygonID, mesh))
sel_svc.EndBatch ()
layer_scan.Apply ()
lx.bless (ExpandByMaterial_Cmd, 'ffr.expandByMat')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment