The methods documented in this topic provide low-level access to 3ds Max's graphics system. These methods are available for scripts to do any graphics work not possible using the standard high-level graphics methods.
These methods are for use in the existing 3ds Max viewports, and only work on the active viewport. Note that these methods typically are not for casual use, as they are not intended to be a high level graphics library. For example, many steps are required to display a single lit polygon. These methods are optimized for speed, and not at all for script programmer ease of use.
The methods described in this topic actually operate on graphic windows. While graphic windows are not the same as viewports, they are related to one another. Each viewport has its own graphics window, and the contents of the viewport display can be thought of as a snapshot of the graphics window contents. Since writing to display memory a relatively slow operation, 3ds Max writes instead to the graphics window, and then when all the writes have been finished, it redraws the viewports with the graphics window contents.
in 3ds Max 2012:The Nitrous Graphics Manager introduced in 3ds Max 2012 performs continuous updates to refine the final image. This requires special handling of all Graphics Methods described further in this topic. These Methods will only be executed if they are wrapped in a Scene Redraw Callback function.
In other words, existing scripts will have to be modified to check for the Nitrous Graphics Manager if running 3ds Max 2012 or higher and call all viewport drawing operations from a Scene Redraw Callback function, and newly developed scripts must take this into account and implement the same approach.
The following script will display the class, name and position of every object in the scene:
While the above example would also work in older versions of 3ds Max and using the Direct3D driver, this is the ONLY way to implement gw Viewport Drawing methods when using the Nitrous Graphics Manager in 3ds Max 2012.
on an nVidia card using MAXtreme drivers, the result would look like
This is used to indicate to 3ds Max (and the mesh class in particular) that the driver wants to handle all of the 3D data natively. In this case, meshes are rendered by passing 3D world space data and letting the driver transform, clip, and light the vertices. If this returns false , then the mesh class handles all transforms, clipping and lighting calculations and then calls the hPolygon or hPolyline 2 1/2D calls for the driver to rasterize. (Primitives that are actually clipped are still sent to the polygon/polyline methods.)
If this returns true , then 3ds Max will try to stripify meshes before calling the rendering methods. Currently, the drivers just return the user preference that is set in the driver configuration dialog. This preference defaults to true .
If a driver has dual-planes support it returns true. The standard 3ds Max OpenGL display driver only returns true for this if the underlying display driver has implemented a custom OpenGL extension that allows 3ds Max to handle this efficiently.
This returns true if the driver can update a rectangular subset of the viewport without trashing the image outside that rectangle. This is true for most drivers that blit the viewport region and false for those that do page-flipping in the hardware. For OpenGL, this is true if the display driver implements the Microsoft glSwapRectHintWIN extension.
This is true if WM_PAINT messages result in a blit of the backbuffer (as opposed to a page-flipping swap). This allows 3ds Max to do quick damage region repair, and works together with the #swapModel flag.
This is true if the driver wants 3ds Max to send down wireframe models using triangle strips instead of a bundle of 2-point segments. This is only used by the OpenGL driver, and it is there as a user-choosable performance-accuracy tradeoff (since the strips are faster and are back-culled, but they display hidden edges as though they are visible).
Sets the active viewport’s graphics window transformation matrix to the specified matrix3 value, and updates the modeling coordinates to normalized projection coordinates matrix. This routine also back-transforms each light and the eye point so that lighting can be done in modeling coordinates.
This method may be used to set a matrix that transforms the point passed to the drawing methods (like gw.text() , gw.marker() , gw.polyline() or gw.polygon() ). Normally these methods expect world coordinates. However if this matrix is set to an object’s transformation matrix you can pass coordinates in the object’s space coordinates and they will be transformed into world space (and then put into screen space when they are drawn). If however this is set to the identity matrix, you would pass world space coordinates. You can set this matrix to the object’s transform matrix using the following
For world-to-screen space conversions by the methods gw.text() , gw.marker() , gw.polyline() or gw.polygon() , etc, a developer must explicitly set this matrix to the identity matrix. This is because the graphics window may have a non-identity transform matrix already in place from a previous operation.
Sets the size and position of the graphics window. The coordinates are all Windows coordinates in the space of the graphics windows' parent window. All coordinates are in Windows format, with the origin in the upper left.
This method resets the update rectangle. The update rectangle is the region of the screen that needs to be updated to reflect items that have changed. When the system is done rendering items, the goal is to only update the region of the viewport that has actually been altered. This method sets the update rectangle (the region that will be blitted to the display) to a special "empty" value. This way when gw.enlargeUpdateRect() is later called, the Box2 region passed will be used as the region.
Sets the rendering limits used by primitive calls. Setting the rendering limits is used in communication between the various parts of 3ds Max that handle the display of objects. For example, setting this limit to #polyEdges and then drawing a polygon won't result in a polygon drawn with edges. It only sets a flag that indicates the edge should be drawn.
What happens is as follows. Inside the upper level 3ds Max, part of the code knows that polygon edges have been turned on. However this is not related through the object oriented architecture to the part of 3ds Max that does the actual drawing. When 3ds Max goes to draw objects it will see that the polygon edge flag is on. This tells it to do two drawing passes -- one to draw the polygon, then it calls outlinePass() call with true , draws a bunch of edges, then calls outlinePass() with false . Thus, the drawing routine is responsible for looking at the flags and drawing appropriately. This method is only responsible setting the limit which can later be checked.
This modifies #colorVerts . If set, lighting is enabled and the vertex colors are used to modulate the colors that result from lighting. If off, the colors on each vertex are used directly to shade the triangle. When 3ds Max uses #shadeCverts mode, it puts a white diffuse-only material on the object so that it appears that the colors are shaded without distortion.
When #shadeCverts is ON, the diffuse white material is illuminated by the scene lighting, resulting in shades ranging from black to white, with most vertices being some shade of pure gray. When the vertex colors are modulated by the material color, they get multiplied (in general) by a number less than 1, which makes them appear darker.
The RGB components of the colors are modulated uniformly, so that there is no shift from, say, red to green. That would happen if the underlying material was not evenly weighted (that is, a pure gray lying between black and white). Said another way, only the intensity of the vertex colors is changed when shading is on, not luminance, chrominance, etc.
This mode is really a pseudo-mode, in that it doesn't actually cause the graphics drivers to do anything differently, but rather is tested by the Mesh class, which sends down vertex markers (+) if the mode is on.
When coordinates are specified for drawing primitives they have x, y, and z values. Sometimes when drawing entities in the viewports it is desirable to ignore the z values. For example in the 3ds Max viewports the text that display the type of viewport (Front, Left, and so on) are drawn without z values. So are the arc-rotate circle control and the axis tripods. These items are drawn without this flag being set so they always show up in front.
Returns the current rendering mode used by the viewport as an array of names. This is a subset of the rendering limit, in that any limits imposed by the rendering limit are forced onto the current mode. See gw.setRndLimits() for a list of the returned name values.
Sets the number of triangles skipped when the viewport is set as a 'Fast View Display' viewport. To disable fastview, specify 1. Since triangles are handed down to graphics driver one at a time, it is up to the code that feeds triangles to the graphics driver to skip the specified number of triangles. The mesh rendering in 3ds Max uses the skip count in this way.
The following is an example of using the above functions
Exposes the Display All Triangle Edges option available in the UI as a checkbox in the Customize>Preferences>Viewports>Configure Driver dialog of the Direct3D driver. When set to true, all edges will be drawn. When set to false, only visible edges will be drawn.
The following methods map points from the graphic window's current transform to device space. If the graphic window's transform is set to the identity matrix then the mapping is done from points specified in world space. Otherwise the points given are transformed by the graphic window’s transform, and are then considered to be in world space. Thus, o get a world-space to screen-space conversion, you need to set the graphic window’s transform to the identity with
This method converts the point3 coordinate to a "h" format device coordinate. Each component of the return value is in integer format in the native device coordinates for the graphics driver. For HEIDI and OpenGL, the origin is at the lower left. For Direct3D the origin is at the upper left.
This method converts the point3 coordinate to a "h" floating point coordinate. Each component of the return value is in float format with the origin at the upper left. This is just a helper routine to avoid building up round-off error. 3ds Max uses it just for IK.
Methods that start with "h" take integer device coordinates with the origin at the lower-left. Methods that start with "w" in front take Windows device coordinates with the origin at the upper left. These "h" and "w" routines perform NO clipping unless otherwise noted. Drawing outside the allowable region is likely to cause 3ds Max to crash. These coordinate systems are left-handed.
Methods that don’t start with "h" or "w" map points from the graphic window's current transform to device space. This coordinate system is right-handed. If the graphic window's transform is set to the identity matrix then the mapping is done from points specified in world space. Otherwise the points given are transformed by the graphic window’s transform, and are then considered to be in world space. Thus, to get a world-space to screen-space conversion, you need to set the graphic window’s transform to the identity with:
gw.text <point3> <string> [ color:<color> ] gw.hText <point3> <string> [ color:<color> ] gw.wText <point3> <string> [ color:<color> ]
gw.Marker <point3> <marker_name> [ color:<color> ] gw.hMarker <point3> <marker_name> [ color:<color> ] gw.wMarker <point3> <marker_name> [ color:<color> ]
Draws a marker at the specified location. This is can be paired with pickpoint() to quickly show where the user has clicked. These markers are temporary and will be erased whenever the viewports are updated. If the color is not specified, a default color of red is used. The valid <marker_name> types are:
#point #hollowBox #plusSign #asterisk #xMarker #bigBox #circle #triangle #diamond #smallHollowBox #smallCircle #smallTriangle #smallDiamond
gw.Polyline <vertex_point3_array> <isClosed_boolean> [rgb:<color_array>] gw.hPolyline <vertex_point3_array> <isClosed_boolean> [rgb:<color_array>] gw.wPolyline <vertex_point3_array> <isClosed_boolean> [rgb:<color_array>]
This method draws a multi-segment polyline. Each value in <vertex_point3_array> is a vertex on the polyline. If <isClosed_boolean> is true , the first point is connected to the last point, that is, the polyline is closed. If false , the polyline is left open. If the optional rgb color array is specified, and shade mode is set to smooth, the polyline will be drawn Gourand shaded. This is how 3ds Max draws lit wireframes for instance. If the optional rgb color array is not specified, the line is drawn with the line color specified via gw.setColor() . The number of elements in <color_array> must be the same as in <vertex_point3_array> .
gw.Polygon <vertex_point3_array> <color_array> <uvw_point3_array> gw.hPolygon <vertex_point3_array> <color_array> <uvw_point3_array> gw.wPolygon <vertex_point3_array> <color_array> <uvw_point3_array>
This method draws a multi-point polygon. Each value in <vertex_point3_array> is a vertex on the polygon. <color_array> specifies the color at each vertex. The rendering mode (set via gw.setRndLimits() ) must include #illum for the color values to be used. <uvw_point3_array> specifies the UVW coordinates at each. The rendering mode must include #texture for the UVW coordinates to be used. The number of elements in each array must be identical.
rect = (box2 13 47 96 97) gw.wrect rect red gw.wmarker [rect.left,rect.top,0] #point color:green gw.wmarker [rect.left,rect.bottom,0] #point color:green gw.wmarker [rect.right,rect.top,0] #point color:green gw.wmarker [rect.right,rect.bottom,0] #point color:green eRect = rect -- enlargeUpdateRect 1 pixel too small in either direction? eRect.right += 1 eRect.bottom += 1 gw.enlargeUpdateRect eRect gw.updateScreen()
The method takes 3 or more vertices and builds triangles in a strip. This sends a lot less data and the underlying graphics library has to set up a lot less data since it can use the previous information to start the rasterization, resulting in a significant speed increase. This routine does no clipping so all the vertices passed must be within view.
The parameters are the same as for the gw.Polygon() . However, the <vertex_point3_array> is handled differently. After the first two vertices, each new vertex is used to create a new triangle. For instance, to draw a quad, the first three vertices specify the first triangle and the next one is combined with the previous two to complete the square.
gw.hTriStrip <vertex_point3_array> <color_array> <uvw_point3_array> gw.wTriStrip <vertex_point3_array> <color_array> <uvw_point3_array>
#line -- line drawing color #fill -- polygon fill color #text -- text drawing color #clear -- The color that the viewport is cleared to when you call gw.clearScreen()
Clears the specified rectangular region of the screen. If the optional useBkg parameter is set to false , the region is set to the "clear" color (see gw.setColor() above). If true , the background should be used to fill the cleared area. The default useBkg value is false .