1 from __future__
import division
27 from builtins
import next
28 from builtins
import range
32 from maya.api
import OpenMaya, OpenMayaRender, OpenMayaUI
33 from maya
import OpenMayaRender
as OpenMayaRenderV1
35 logger = logging.getLogger(
'lassoTool')
43 This context command class creates instances of the LassoToolContext.
45 kPluginCmdName =
"py2LassoToolContext"
53 This factory method creates an instance of the LassoToolContextCmd class.
59 This factory method creates an instance of the LassoToolContext class.
61 return LassoToolContext()
65 This context class extends a bounding box as the user drags the cursor during a selection
69 help_string =
"Drag mouse to select points by encircling"
75 cursor_bits = bytearray( [
76 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x10, 0x08, 0x10, 0x10, 0x08, 0x10,
77 0x08, 0x10, 0x08, 0x10, 0x08, 0x08, 0x08, 0x08, 0x14, 0x08, 0x14, 0x04,
78 0x08, 0x07, 0xf4, 0x00, 0x02, 0x00, 0x01, 0x00] )
79 cursor_mask_bits = bytearray( [
80 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x10, 0x08, 0x10, 0x10, 0x08, 0x10,
81 0x08, 0x10, 0x08, 0x10, 0x08, 0x08, 0x08, 0x08, 0x14, 0x08, 0x14, 0x04,
82 0x08, 0x07, 0xf4, 0x00, 0x02, 0x00, 0x01, 0x00] )
87 Create and return an instance of the LassoToolContext class.
89 return LassoToolContext(cls)
93 Initialize the context member variables.
97 self.sorted_lasso = []
99 height=self.cursor_height,
100 hotSpotX=self.cursor_x_hot,
101 hotSpotY=self.cursor_y_hot,
102 bits=self.cursor_bits,
103 mask=self.cursor_mask_bits)
105 self.first_draw =
False
106 self.list_adjustment = 0
108 self.setTitleString(
'Lasso Tool')
111 self.setCursor(self.lasso_cursor)
114 self.setImage(
'lassoTool.xpm', OpenMayaUI.MPxContext.kImage1)
116 def stringClassName(self):
118 Return the class name string.
122 def toolOnSetup( self, event ):
124 Perform any setup operations when the tool is created. In this case,
127 self.setHelpString( LassoToolContext.help_string )
129 def do_press_common( self, event ):
131 Perfom the press operations common to both VP2.0 and the Legacy Viewport.
136 if event.isModifierShift()
or event.isModifierControl():
137 if event.isModifierShift():
138 if event.isModifierControl():
140 self.list_adjustment = OpenMaya.MGlobal.kAddToList
143 self.list_adjustment = OpenMaya.MGlobal.kXORWithList
145 elif event.isModifierControl():
147 self.list_adjustment = OpenMaya.MGlobal.kRemoveFromList
149 self.list_adjustment = OpenMaya.MGlobal.kReplaceList
151 start = event.position
152 self.lasso.append([start[0], start[1]])
153 self.min = [start[0], start[1]]
154 self.max = [start[0], start[1]]
155 self.first_draw =
True
158 def do_release_common( self, event ):
160 Perfom the release operations common to both VP2.0 and the Legacy Viewport.
164 self.append_lasso(self.lasso[0])
165 self.sorted_lasso = sorted(self.lasso, key=
lambda x: (x[1], x[0]))
175 OpenMaya.MGlobal.kReplaceList )
191 found_entire_objects =
False
192 found_components =
False
194 while not iter.isDone():
196 dag_path = iter.getDagPath()
197 component = OpenMaya.MObject.kNullObj
198 if iter.hasComponents():
199 sel = iter.getComponent()
202 if component.isNull():
204 found_entire_objects =
True
208 found_components =
True
210 if component.apiType() == OpenMaya.MFn.kCurveCVComponent:
212 while not curve_cv_iter.isDone():
214 point = curve_cv_iter.position(OpenMaya.MSpace.kWorld)
215 pt = self.view.worldToView(point)
216 if self.point_in_lasso(pt):
217 single_component = curve_cv_iter.currentItem()
218 new_list.add ((dag_path, single_component))
223 elif component.apiType() == OpenMaya.MFn.kSurfaceCVComponent:
225 while not surf_cv_iter.isDone():
227 point = surf_cv_iter.position(OpenMaya.MSpace.kWorld)
228 pt = self.view.worldToView(point)
229 if self.point_in_lasso(pt):
230 single_component = surf_cv_iter.currentItem()
231 new_list.add((dag_path, single_component))
236 elif component.apiType() == OpenMaya.MFn.kMeshVertComponent:
238 while not vertex_iter.isDone():
240 point = vertex_iter.position(OpenMaya.MSpace.kWorld)
241 pt = self.view.worldToView(point)
242 if self.point_in_lasso(pt):
243 single_component = vertex_iter.currentItem()
244 new_list.add((dag_path, single_component))
249 elif component.apiType() == OpenMaya.MFn.kMeshEdgeComponent:
251 while not edge_iter.isDone():
253 point = edge_iter.center(OpenMaya.MSpace.kWorld)
254 pt = view.worldToView(point)
255 if self.point_in_lasso(pt):
256 single_component = edge_iter.currentItem()
257 new_list.add ((dag_path, single_component))
262 elif component.apiType() == OpenMaya.MFn.kMeshPolygonComponent:
264 while not polygon_iter.isDone():
266 point = polygon_iter.center(OpenMaya.MSpace.kWorld)
267 pt = view.worldToView(point)
268 if self.point_in_lasso(pt):
269 single_component = polygon_iter.currentItem();
270 new_list.add ((dag_path, single_component))
278 if found_entire_objects
and (
not found_components):
286 self.sorted_lasso = []
288 def draw_lasso_gl( self ):
290 Draw the lasso using OpenGL. This method is used by the Legacy Viewport.
295 gl_renderer = OpenMayaRenderV1.MHardwareRenderer.theRenderer()
296 gl_ft = gl_renderer.glFunctionTable()
297 gl_ft.glBegin( OpenMayaRenderV1.MGL_LINE_LOOP )
298 for i
in range(len(self.lasso)):
299 gl_ft.glVertex2i( self.lasso[i][0], self.lasso[i][1] );
304 def append_lasso( self, pt ):
306 Append the given point to the points defining the lasso.
310 [ix, iy] = self.lasso[-1]
311 ydif = int(math.fabs( y - iy ))
317 if ( self.min[0] > x ):
319 if ( self.max[0] < x ):
321 if ( self.min[1] > y ):
323 if ( self.max[1] < y ):
334 for i
in range(ydif):
335 self.lasso.append([int(fx), int(cy)])
339 def point_in_lasso( self, pt ):
341 Check the given point to see if it's inside the loop defined by the lasso.
343 for i
in range(len(self.lasso)):
344 if (self.sorted_lasso[i][1] == pt[1]):
345 while ((self.sorted_lasso[i][1] == pt[1])
and (self.sorted_lasso[i][0] < pt[0])):
347 if (self.sorted_lasso[i][1] != pt[1]):
351 while (self.sorted_lasso[i][1] == pt[1]):
361 def doPressLegacy( self, event ):
363 Handle the mouse press event in the Legacy Viewport.
365 self.do_press_common(event)
366 self.first_draw =
False
368 def doDragLegacy( self, event ):
370 Handle the mouse drag event in the Legacy Viewport. Add to the growing lasso.
372 self.view.beginXorDrawing(
True,
True, 1.0, OpenMayaUI.M3dView.kStippleDashed)
373 if not self.first_draw:
377 self.first_draw =
False
380 current_pos = event.position
381 self.append_lasso( current_pos )
385 self.view.endXorDrawing()
387 def doReleaseLegacy( self, event ):
389 Handle the mouse release event in the Legacy Viewport.
394 self.view.beginXorDrawing(
True,
True, 1.0, OpenMayaUI.M3dView.kStippleDashed);
396 self.view.endXorDrawing()
398 self.do_release_common( event );
400 def doPress( self, event, drawMgr, context ):
402 Handle the mouse press event in VP2.0.
404 self.do_press_common(event)
406 def doRelease( self, event, drawMgr, context ):
408 Handle the release press event in VP2.0.
410 self.do_release_common(event)
412 def doDrag( self, event, draw_mgr, context ):
414 Handle the mouse drag event in VP2.0.
417 current_pos = event.position
418 self.append_lasso( current_pos )
421 draw_mgr.beginDrawable()
423 for i
in range(len(self.lasso)-1):
424 draw_mgr.line2d(
OpenMaya.MPoint( (self.lasso[i][0], self.lasso[i][1])), \
428 draw_mgr.line2d(
OpenMaya.MPoint( (self.lasso[-1][0], self.lasso[-1][1])), \
430 draw_mgr.endDrawable()
432 def doEnterRegion( self, event ):
434 Handle the enter region event. This method is called from both VP2.0 and the Legacy Viewport.
436 self.setHelpString( LassoToolContext.help_string )
439 def initializePlugin(plugin):
443 pluginFn.registerContextCommand( LassoToolContextCmd.kPluginCmdName, LassoToolContextCmd.creator)
445 logger.error(
"Failed to register context command: %s\n" % LassoToolContextCmd.kPluginCmdName)
450 def uninitializePlugin(plugin):
453 pluginFn.deregisterContextCommand(LassoToolContextCmd.kPluginCmdName)
455 logger.error(
"Failed to unregister command: %s\n" % LassoToolContextCmd.kPluginCmdName)