# MeshEditOp¶

An instance of this class is returned by the LWModCommand.editBegin() method (see Command Sequence in Handler Interfaces), and contains data and functions for performing mesh editing tasks.

class lwsdk.MeshEditOp(*args)

Bases: object

Proxy of C++ PCore::MeshEditOp class

 addCurve(state, char surf, array[], int flags) → LWPolID

Create a curve (a polygon of type lwsdk.LWPOLTYPE_CURV). The lwsdk.EDPF_CCSTART and lwsdk.EDPF_CCEND flags specify that the first and last points in the point array should serve as control points and not be included in the curve itself. To create a closed curve, both of these flags must be set, and the first and last point must overlap.

 addFace(state, char surf, array[]) → LWPolID

Create a polygon. If the surface name is None, the polygon will be assigned the current default surface. The vertices are defined by an array of point IDs listed in clockwise order. The polygon normal will be inferred from the first, second and last points.

 addIPnt(state, double xyz, int numPnt, LWPntID arg2, double wt) → LWPntID

!!! NOT IMPLEMENTED !!!

 addPatch(state, int nr, int nc, int lr, int lc, r0[], r1[], c0[], c1[]) → EDError

Create a polygonal patch defined by three or four bounding curves. The first two arguments, nr and nc, give the number of patch divisions in the R (row) and C (column) directions. The second two arguments, lr and lc, are Booleans; if 0, the divisions are equally spaced along the curve, and if 1, the spacing is determined by the positions of the curve knots. The last four arguments are the bounding curves, each defined by an array of EDBoundCV structures.

 addPoint(state, pos[]) → LWPntID

Create a new point in the current editing session.

 addPoly(state, LWID type, LWPolID template, char surf, points[]) → LWPolID

Create a polygon. If template is not None, Modeler copies the polygon tags for the new polygon from the template. If the surface name is None, the surface will be that of template, or the current default surface if template is None. The vertices of the new polygon are listed in clockwise order, and the normal will be inferred from the first, second and last vertex.

 addQuad(state, LWPntID pnt1, LWPntID pnt2, LWPntID pnt3, LWPntID pnt4) → EDError

Create a quadrangle with the current default surface. The function respects the user's settings for new geometry. Two collocated polygons with opposite normals will be created if the user has set the double-sided option, and quads will be split into two triangles if the user has set the triangles-only option.

 addTri(state, LWPntID pnt1, LWPntID pnt2, LWPntID pnt3) → EDError

Create a triangle with the current default surface. The function respect the user's settings for new geometry. Two collocated polygons with opposite normals will be created if the user has set the double-sided option.

 advanceLayer(state) → int

Advances the current layer for new geometry to the next available layer in the current edit context, returns the layer index if the layer is valid and was set, otherwise it will return 0 if already on the last layer in the list.

 done(state, EDError result, int selset)

Call this when the edit is complete. As changes are made during an edit, they are buffered through Modeler's undo mechanism, so they are not reflected in the data until done is called, and not at all if done sets the error argument

In general, if one of the edit functions returns an error, you'll pass that error through result. If you just want the edit to stop or be discarded, possibly because the user pressed the Cancel button in a progress monitor, you'll pass lwsdk.EDERR_USERABORT. If an error occurs in your plug-in, you'll pass lwsdk.EDERR_NOMEMORY (for memory allocation errors) or lwsdk.EDERR_BADARGS (for everything else). And if the edit was successful, you'll use lwsdk.EDERR_NONE.

The selset argument tells Modeler how you want the selection to appear to the user after the edit has been applied. It contains flags combined using bitwise-or, and can include the following.

lwsdk.EDSELM_CLEARCURRENT: Deselect elements that were selected when the edit began.
lwsdk.EDSELM_SELECTNEW: Select elements created by the edit.
lwsdk.EDSELM_FORCEVRTS: Force selection of newly created vertices.
lwsdk.EDSELM_FORCEPOLS: Force selection of newly created polygons.

A value of 0 leaves all directly selected elements selected after the edit. The lwsdk.EDSELM_CLEARCURRENT and lwsdk.EDSELM_SELECTNEW flags are polite hints; they won't override selection settings made by the user. The force flags will always force direct selection of the points or polygons created by the edit.

 edgeCount(state, EltOpLayer layer, int mode) → int

Returns the number of edges that meet the layer and selection mode criteria. The selection mode can be one of the following:

lwsdk.EDCOUNT_ALL: Both selected and unselected edges.
lwsdk.EDCOUNT_SELECT: Only selected edges.
lwsdk.EDCOUNT_DELETE: Only edges flagged for deletion by this mesh edit.

 edgeData(state, LWEdgeID edge) → bytes[]

Returns the data associated with the specified element. This is the data allocated during the MeshEditBegin call.

Note that the return value is a pointer to raw binary data, so you will need to use something like ctypes to access it.

 edgeFlags(state, LWEdgeID edge) → int

Returns the flags associated with the specified element. These are the same values as the flags field found in the EDEdgeInfo structure.

 edgeFlip(state, LWEdgeID edge)

!!! NOT DOCUMENTED !!!

 edgeFromPoints(state, LWPntID pnt1, LWPntID pnt2) → LWEdgeID

Returns the edge between p1 and p2 if such an edge exists. Otherwise, the function returns None.

 edgeInfo(state, LWEdgeID edge) → EDEdgeInfo

Returns information about an edge. This returns the same EDEdgeInfo structure that is passed to the edge-scan callbacks.

 edgeLayer(state, LWEdgeID edge) → int

Returns an integer for the layer number of the edge.

 edgeNew(state, LWEdgeID edge) → int

Returns 1 if the element has been created in the current edit context, 0 if the element already existed.

 edgePoint1(state, LWEdgeID edge) → LWPntID

Returns the first point making up an edge.

 edgePoint2(state, LWEdgeID edge) → LWPntID

Returns the second point making up an edge.

 edgePolys(state, LWEdgeID edge) → polygons[]

Returns an array of polygon IDs surrounding the specified edge.

 edgeScan(state, callable, userdata, EltOpLayer layer) → EDError

Enumerate edge geometry in the specified layers. For each element, Modeler invokes the callable function you supply for each edge.

The userdata value is passed as the first argument to your callbacks, and it can be whatever is useful to you. The edge info structure passed as the second argument. If your callback returns an error, the scan is stopped and the callback's error is returned.

Edge scans will enumerate all of the geometry in the layers you request, regardless of what geometry is selected, even if you begin the edit with lwsdk.OPSEL_USER or lwsdk.OPSEL_DIRECT. To find out whether a given element is selected (as defined by your choice of EltOpSelect), you need to test the EDEdgeInfo flags field for the lwsdk.EDDF_SELECT bit. Similarly, if you've deleted geometry during the mesh edit, it will still be enumerated, but the flags field of the info structure will contain lwsdk.EDDF_DELETE.

 edgeSelect(state, LWEdgeID edge, int setsel) → EDError

Set the selection state of an edge. This can only be called during lwsdk.OPSEL_MODIFY mesh edits. The element is selected if setsel is 1 and deselected if it is 0.

 fastEdgeScan(state, callable, userdata, EltOpLayer layer, int selected_only) → EDError

This are like the "normal" edge-scan version, but does not provide complete info structures at every iteration, saving considerable processing overhead for those that do not require the complete info structure of each element scanned. Instead, the callable is supplied element IDs from which the necessary data can be extracted. There is also a selected_only parameter which can be specified to 1, in which case the scan function is only applied for the selected elements only. Note that selected_only indicates that only elements that are actually selected will be scanned (same effect as using lwsdk.OPSEL_DIRECT). This is also more efficient than checking for the lwsdk.EDDF_SELECT flag at every scan iteration.

 fastPointScan(state, callable, userdata, EltOpLayer layer, int selected_only) → EDError

This are like the "normal" point-scan version, but does not provide complete info structures at every iteration, saving considerable processing overhead for those that do not require the complete info structure of each element scanned. Instead, the callable is supplied element IDs from which the necessary data can be extracted. There is also a selected_only parameter which can be specified to 1, in which case the scan function is only applied for the selected elements only. Note that selected_only indicates that only elements that are actually selected will be scanned (same effect as using lwsdk.OPSEL_DIRECT). This is also more efficient than checking for the lwsdk.EDDF_SELECT flag at every scan iteration.

 fastPolyScan(state, callable, userdata, EltOpLayer layer, int selected_only) → EDError

This are like the "normal" polygon-scan version, but does not provide complete info structures at every iteration, saving considerable processing overhead for those that do not require the complete info structure of each element scanned. Instead, the callable is supplied element IDs from which the necessary data can be extracted. There is also a selected_only parameter which can be specified to 1, in which case the scan function is only applied for the selected elements only. Note that selected_only indicates that only elements that are actually selected will be scanned (same effect as using lwsdk.OPSEL_DIRECT). This is also more efficient than checking for the lwsdk.EDDF_SELECT flag at every scan iteration.

 genEdges(state, EltOpLayer arg2, int selectedOnly) → LWEdgeGenerator

!!! NOT DOCUMENTED !!!

 genPoints(state, EltOpLayer arg2, int selectedOnly) → LWPointGenerator

!!! NOT DOCUMENTED !!!

 genPolys(state, EltOpLayer arg2, int selectedOnly) → LWPolyGenerator

!!! NOT DOCUMENTED !!!

 initUV(state, uvs[]) → EDError

Set the texture UV for a point or polygon you're about to create. If a texture map is selected in Modeler's interface, the UVs will be assigned to that map as points or polygons are created. You'll typically want to give the user the option of whether or not to create UVs for new points and polygons.

When creating points, pass a uvs array of two floats and then call any of the functions that create a point. The two floats will be used as the U and V for the point, after which the state will be cleared so that subsequent points have no UV unless the function is called again.

To initialize per-polygon, or discontinuous, UVs, call with a sequence of 2n floats before creating a polygon with n vertices. For each vertex, if the point's continuous UV value is different from the UV in the array, then a polygon-specific UV is set for the vertex. If the point has no continuous UV, then the continuous value for the point is set to the polygon UV.

Any combination of these two methods can be used to assign UVs to new data. If only polygon UVs are specified, continuous UVs will still be created where polygons share UV values. Alternately, plug-ins can assign UVs to points and only specify polygon UVs along seam polygons.

 layerNum → int

Points and polygons may only be created or modified in the primary active layer, which is given by this layer number. The primary layer is the lowest numbered foreground layer.

 pntMove(state, LWPntID point, pos[]) → EDError

Put a point in a new position.

 pntSelect(state, LWPntID point_id, int setsel) → EDError

Set the selection state of a point. This can only be called during lwsdk.OPSEL_MODIFY mesh edits. The element is selected if setsel is 1 and deselected if it is 0.

 pntVMap(state, LWPntID point, LWID type, char name, values[]) → EDError

Add a vmap vector to a point. The vmap type can be one of the following, or something else:

lwsdk.LWVMAP_PICK: selection set
lwsdk.LWVMAP_WGHT: weight map
lwsdk.LWVMAP_MNVW: subpatch weight map
lwsdk.LWVMAP_TXUV: texture UV coordinates
lwsdk.LWVMAP_MORF: relative vertex displacement (morph)
lwsdk.LWVMAP_SPOT: absolute vertex displacement (morph)
lwsdk.LWVMAP_RGB, lwsdk.LWVMAP_RGBA: vertex color
lwsdk.LWVMAP_NORM: vertex normals

Pass None for the values array argument to remove a vmap vector from the point.

 pntVPMap(state, LWPntID point, LWPolID polygon, LWID type, char name, values[]) → EDError

Add a discontinuous vmap vector to a polygon vertex. This is the vector returned by MeshEditOp.pointVPGet(). See MeshEditOp.pntVMap() above for a partial list of vmap types.

 pointCount(state, EltOpLayer layer, int mode) → int

Returns the number of points that meet the layer and selection mode criteria. The selection mode can be one of the following:

lwsdk.EDCOUNT_ALL: Both selected and unselected points.
lwsdk.EDCOUNT_SELECT: Only selected points.
lwsdk.EDCOUNT_DELETE: Only points flagged for deletion by this mesh edit.

 pointData(state, LWPntID point) → void

Returns the data associated with the specified element. This is the data allocated during the MeshEditBegin call.

 pointEdges(state, LWPntID point) → PyObject

Returns the edges surrounding the specified point.

 pointFlags(state, LWPntID point) → int

Returns the flags associated with the specified element. These are the same values as the flags field found in the EDPointInfo structure.

 pointInfo(state, LWPntID point)

Returns information about a point. This returns the same EDPointInfo structure that is passed to the point-scan callbacks.

 pointLayer(state, LWPntID point) → int

Returns an integer for the layer number of the point.

 pointNew(state, LWPntID point) → int

Returns 1 if the element has been created in the current edit context, 0 if the element already existed.

 pointPos(state, LWPntID point) → pos[3]

Returns the position of the specified point.

 pointScan(state, callable, userdata, EltOpLayer layer) → EDError

Enumerate point geometry in the specified layers. For each element, Modeler invokes the callable function you supply for each point.

The userdata value is passed as the first argument to your callbacks, and it can be whatever is useful to you. The point info structure passed as the second argument. If your callback returns an error, the scan is stopped and the callback's error is returned.

Point scans will enumerate all of the geometry in the layers you request, regardless of what geometry is selected, even if you begin the edit with lwsdk.OPSEL_USER or lwsdk.OPSEL_DIRECT. To find out whether a given element is selected (as defined by your choice of EltOpSelect), you need to test the EDPointInfo flags field for the lwsdk.EDDF_SELECT bit. Similarly, if you've deleted geometry during the mesh edit, it will still be enumerated, but the flags field of the info structure will contain lwsdk.EDDF_DELETE.

 pointVEval(state, LWPntID point, LWPolID polygon) → (ismapped, values[])

Read the vmap vector for a point, accounting for both continuous and discontinuous values. Generally, if a discontinuous value exists for the point, that value will be returned. Otherwise the continuous value is used.

 pointVGet(state, LWPntID point) → (ismapped, values[])

Read the vmap vector for a point. The vector is read from the vmap selected by a previous call to MeshEditOp.pointVSet(). The ismapped value will be 1 if the point has a vmap value in the selected vmap.

 pointVPGet(state, LWPntID point, LWPolID polygon) → (ismapped, values[])

Read the vmap vector for a polygon vertex. This is like MeshEditOp.pointVGet(), but it returns the discontinuous vmap value (equivalent to reading entries in a VMAD chunk).

 pointVSet(state, vmapID, LWID type, char name) → vmapID

Select a vmap for reading vectors. Returns an opaque pointer vmapID that can be used to select the same vmap in later calls to this function. The first time this is called for a given vmap, the vmapID parameter can be None, and Modeler will locate and select the vmap using the type and name arguments.

 polFlag(state, LWPolID polygon, int mask, int value) → EDError

Set polygon flags. The mask contains 1 bits for each flag you want to change, and the value contains the new flag settings (0 or 1 for each 1 bit in the mask). Currently, the flags that can be changed are the lwsdk.EDPF_START and lwsdk.EDPF_END flags for curves.

 polPnts(state, LWPolID polygon, points[]) → EDError

Replace the point list of a polygon.

 polSelect(state, LWPolID polygon, int setsel) → EDError

Set the selection state of a polygon. This can only be called during lwsdk.OPSEL_MODIFY mesh edits. The element is selected if setsel is 1 and deselected if it is 0.

 polSurf(state, LWPolID polygon, char surf) → EDError

Change the surface assigned to a polygon.

 polTag(state, LWPolID polygon, LWID type, char tag) → EDError

Add a polygon tag to a polygon, or change an existing tag. If the tag type is lwsdk.LWPTAG_SURF, the tag is the surface name. If the tag type is lwsdk.LWPTAG_PART, the tag is the part (or group) name. For anything other than surface tags, passing None will remove an existing tag of the specified type.

polType(self, EDStateRef es, LWPolID pol, unsigned int type) → EDError
 polyCount(state, EltOpLayer layer, int mode) → int

Returns the number of polygons that meet the layer and selection mode criteria. The selection mode can be one of the following:

lwsdk.EDCOUNT_ALL: Both selected and unselected polygons.
lwsdk.EDCOUNT_SELECT: Only selected polygons.
lwsdk.EDCOUNT_DELETE: Only polygons flagged for deletion by this mesh edit.

 polyData(state, LWPolID polygon) → ptr

Returns the data associated with the specified element. This is the data allocated during the MeshEditBegin call.

 polyFlags(state, LWPolID polygon) → int

Returns the flags associated with the specified element. These are the same values as the flags field found in the EDPolygonInfo structure.

 polyInfo(state, LWPolID polygon) → EDPolygonInfo

Returns information about a polygon. This returns the same EDPolygonInfo structure that is passed to the polygon-scan callbacks.

 polyLayer(state, LWPolID polygon) → int

Returns an integer for the layer number of the polygon.

 polyNew(state, LWPolID polygon) → int

Returns 1 if the element has been created in the current edit context, 0 if the element already existed.

 polyNormal(state, LWPolID polygon) → (ok, normal[3])

Get a polygon's normal. The normal is a unit vector perpendicular to the plane defined by the first, second and last vertex of the polygon. If the polygon has fewer than three vertices, or is somehow degenerate, ok will be 0. Otherwise, ok will be 1 and normal will contain a valid vector.

 polyPoints(state, LWPolID polygon) → points[]

Returns the vertices making up the specified polygon.

 polyScan(state, callable, userdata, EltOpLayer layer) → EDError

Enumerate polygon geometry in the specified layers. For each element, Modeler invokes the callable function you supply for each polygon.

The userdata value is passed as the first argument to your callbacks, and it can be whatever is useful to you. The polygon info structure passed as the second argument. If your callback returns an error, the scan is stopped and the callback's error is returned.

Polygon scans will enumerate all of the geometry in the layers you request, regardless of what geometry is selected, even if you begin the edit with lwsdk.OPSEL_USER or lwsdk.OPSEL_DIRECT. To find out whether a given element is selected (as defined by your choice of EltOpSelect), you need to test the EDPolygonInfo flags field for the lwsdk.EDDF_SELECT bit. Similarly, if you've deleted geometry during the mesh edit, it will still be enumerated, but the flags field of the info structure will contain lwsdk.EDDF_DELETE.

 polySurface(state, LWPolID polygon) → char

Returns a language encoded string for the surface name assigned to the polygon.

 polyTag(state, LWPolID polygon, LWID type) → char

Returns a tag string associated with the polygon. For the lwsdk.LWPTAG_SURF tag type, the surface name is returned.

 polyType(state, LWPolID polygon) → unsigned int

!!! NOT DOCUMENTED !!!

 remPoint(state, LWPntID point) → EDError

Delete the point. Modeler will flag the point as deleted, but will actually remove it from the database only after MeshEditOp.done() is called.

 remPoly(state, LWPolID polygon) → EDError

Delete the polygon.

 setLayer(state, int layer) → int

Sets the current layer for new geometry to the integer layer, returning 1 if the layer is valid and was set, otherwise it will return 0.

setSmoothingGroups(self, EDStateRef es, LWPolID pol, int arg1, int arg2) → int
smoothingGroups(self, EDStateRef es, LWPolID pol) → int
 state → EDStateRef

An opaque pointer to data used internally by Modeler during the mesh edit. Pass this as the first argument to all of the edit functions.

 vMapExists(state, char vmap_name, LWID type) → int

Tests is the given vertex map name and type already exists. Returns 1 if so, else 0.

 vMapGetDimension(state) → unsigned int

Obtains the dimension count of the state's current vertex map. A value of (0) indicates no vertex map is selected.

 vMapRemove(state)

Removes the state's currently selected vertex map. All existing mappings are removed in the process.

 vMapRename(state, char new_name)

Renames the state's currently selected vertex map to the provided name.

 vMapSelect(state, char name, LWID type, int dim) → vmapID

Selects a vertex map having the given name, type, and optionally a dimension. If the vertex map does not exist and a dimension >= 0 is specified, one is created. Once a vertex map is selected, it becomes part of the state and is used in other vertex map operations. The returned vmap identifier can be used in subsequent calls to MeshEditOp.pointVSet() to make the selection process faster. None is returned if the requested vertex map could not be selected.

 vMapSet(state, LWPntID point, LWPolID polygon, value[])

Sets a mapping of a value vector and a point (optionally a vertex of a polygon). When polygon is None, the mapping will be continuous (associated strictly with the vertex). When polygon is specified, the mapping will be discontinuous (associated with a vertex in a particular polygon). An existing mapping will be overwritten with the provided value vector. Providing a value vector of None will remove the mapping. The dimension of the value vector is assumed to be compatible with the currently selected vertex map. To get the value vector of a particular mapping, use the MeshEditOp.pointVPGet(), MeshEditOp.pointVEval(), and MeshEditOp.pointVGet() routines. This metho shares some functionality with MeshEditOp.pntVMap() and is faster because it does not need to select the vertex map for each call. MeshEditOp.vMapSelect() must be called to select a vertex map first.

 vMapSetIdeal(state, LWPntID point, LWPolID polygon, value[])

Appropriately sets the 'ideal' mapping of a value vector with a point and polygon. If the continuous mapping is not yet set, it will be set to the given value vector. If a continuous mapping is already set and the given value vector differs from the existing one, a discontinuous mapping is added with the given value vector. If a continuous mapping exists and its value is the same as provided, then it is overwritten and any existing discontinuous mapping is removed.