rendering -- 3D user interface¶
This module provides a render pipeline system featuring:
- Class
Sceneto gather the data to render - Widget
Viewthat actually renders the scene - The display protocol, that allows any object to define its
Displaysubclass to be rendered in a scene.
The view is for window integration and user interaction. Scene is only to manage the objects to render. Almost all madcad data types can be rendered to scenes being converted into an appropriate subclass of Display. Since the conversion from madcad data types into display instance is automatically handled via the display protocol, you usually don't need to deal with displays directly.
show(scene, interest=None, size=uvec2(400, 400), projection=None, navigation=True, enable_alpha=False, **options)
¶
Easy and convenient way to create a window containing a `View3D` on a `Scene`
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scene
|
Scene | dict | list
|
a mapping (dict or list) giving the objects to render in the scene |
required |
interest
|
Box
|
the region of interest to zoom on at the window initialization |
None
|
size
|
the window size (pixel) |
uvec2(400, 400)
|
|
projection
|
an object handling the camera projection (aka intrinsic parameters), see |
None
|
|
navigation
|
an object handling the camera movements, see |
True
|
|
options
|
options to set in Parameters:
scene: a mapping (dict or list) giving the objects to render in the scene
interest: the region of interest to zoom on at the window initialization
size: the window size (pixel)
projection: an object handling the camera projection (aka intrinsic parameters), see Tip:
For integration in a Qt window or to manipulate the view, you should directly use |
{}
|
Source code in madcad/rendering/__init__.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |
Display protocol¶
A displayable is an object that implements the signature of Display.
Display(*args)
¶
base class for objects displayed in a scene
Source code in madcad/rendering/base.py
354 355 | |
display(scene)
¶
Displays are obviously displayable as themselves, this should be overriden
Source code in madcad/rendering/base.py
357 358 359 | |
stack(scene)
¶
Rendering functions to insert in the renderpipeline.
The expected result can be any iterable providing tuples (key, target, priority, callable) such as:
The view contains the uniforms, rendering targets and the scene for common resources
Source code in madcad/rendering/base.py
368 369 370 371 372 373 374 375 | |
__getitem__(key)
¶
Get a child display by its key in this display (like in a scene)
Source code in madcad/rendering/base.py
392 393 394 | |
update(scene, src)
¶
Update the current displays internal datas with the given displayable .
If the display cannot be upgraded, it must return False to be replaced by a fresh new display created from the displayable
Source code in madcad/rendering/base.py
361 362 363 364 365 366 | |
control(view, key, sub, evt)
¶
Handle input events occuring on the area of this display (or of one of its subdisplay). For subdisplay events, the parents control functions are called first, and the sub display controls are called only if the event is not accepted by parents
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
tuple
|
the key path for the current display |
required |
sub
|
tuple
|
the key path for the subdisplay |
required |
evt
|
QEvent
|
the Qt event (see Qt doc) |
required |
Source code in madcad/rendering/base.py
377 378 379 380 381 382 383 384 385 386 | |
Rendering system¶
Note
As the GPU native precision is f4 (float 32 bits), all the vector stuff regarding rendering is made using simple precision types: fvec3, fvec4, fmat3, fmat4, ... instead of the usual double precision vec3
Scene(src=None, options=None, context=None, overrides=None)
¶
rendering pipeline for madcad displayable objects
This class is gui-agnostic, it only relies on OpenGL, and the context has to be created by the user.
When an object is added to the scene, a Display is not immediately created for it, the object is put into the queue and the Display is created at the next render. If the object is removed from the scene before the next render, it is dequeued.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
src
|
object
|
the root object of the scene, it must be a displayable and is usually a |
None
|
options
|
dict
|
scene rendering parameters, overriding |
None
|
context
|
Context
|
the openGL context to use to send rendering instructions to the GPU |
None
|
Source code in madcad/rendering/base.py
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | |
root = None
instance-attribute
¶
the root display of the scene, usually a Group
stacks = {}
instance-attribute
¶
a list of the display callbacks for each target frame buffers
touched = False
instance-attribute
¶
trigger for restacking render steps
overrides = deepcopy(Scene.overrides)
class-attribute
instance-attribute
¶
attribute allowing to alter how the displayable are transformed into displays
- the class attribute stores default overrides
- the instance attribute stores the effective overrides for the scene
options = deepcopy(settings.scene)
instance-attribute
¶
scene rendering parameters, deriving from settings.scene
shared = {}
instance-attribute
¶
strong references to the resources we don't want to free when no display is using them
context = mgl.create_standalone_context(requires=opengl_version)
instance-attribute
¶
opengl context used in this scene's displays. It is assumed to have gc_mode = auto
selection = set()
instance-attribute
¶
current set of selected displays (readonly, use the scene methods to alter the selection)
hover = property(_get_hover, _set_hover)
class-attribute
instance-attribute
¶
current display being hovered (readwrite)
update(src)
¶
update the root display of the scene
Source code in madcad/rendering/base.py
93 94 95 96 97 98 99 | |
touch()
¶
inform the scene than its composition changed and that it needs to recompute its call stack
Source code in madcad/rendering/base.py
101 102 103 | |
display(obj, former=None)
¶
Create a display for the given object for the current scene.
This is the actual function converting objects into displays. You don't need to call this method if you just want to add an object to the scene, use add() instead
Source code in madcad/rendering/base.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | |
displayable(obj)
¶
return whether the given object could be displayed in the scene
Source code in madcad/rendering/base.py
150 151 152 153 154 155 156 157 158 159 160 161 | |
share(key, generator=None)
¶
Get a shared resource loaded or load it using the function func. If func is not provided, an error is raised
Source code in madcad/rendering/base.py
163 164 165 166 167 168 169 170 171 172 173 174 | |
prepare()
¶
convert all displayable to displays and bufferize everything for comming renderings
Source code in madcad/rendering/base.py
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | |
render(view)
¶
Render to the view targets.
This must be called by the view widget, once the OpenGL context is set.
Source code in madcad/rendering/base.py
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | |
selection_add(display, sub=None)
¶
select the given display
Source code in madcad/rendering/base.py
222 223 224 225 226 227 228 229 230 231 232 233 | |
selection_remove(display, sub=None)
¶
deselect the given display
Source code in madcad/rendering/base.py
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | |
selection_toggle(display, sub=None)
¶
Source code in madcad/rendering/base.py
252 253 254 255 256 257 258 259 260 261 262 | |
selection_clear()
¶
deselect all previously selected displays
Source code in madcad/rendering/base.py
264 265 266 267 268 269 270 271 272 273 274 | |
__getitem__(key)
¶
Source code in madcad/rendering/base.py
308 309 | |
__setitem__(key, value)
¶
Source code in madcad/rendering/base.py
311 312 | |
item(key)
¶
Source code in madcad/rendering/base.py
314 315 316 317 | |
Views classes¶
GLView3D(scene, size=None, view=None, proj=None, enable_ident=True, enable_alpha=False, **uniforms)
¶
pure openGL 3D view over a madcad scene
Source code in madcad/rendering/d3/view.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | |
scene = scene if isinstance(scene, Scene) else Scene(scene)
instance-attribute
¶
madcad scene to render, it must contain 3D displays (at least a the root)
screen = None
instance-attribute
¶
color map (and depth) openGL buffer
ident = None
instance-attribute
¶
identification map (and depth) openGL buffer
targets = []
instance-attribute
¶
exposed for Scene
uniforms = uniforms
instance-attribute
¶
exposed for Scene
view = view
instance-attribute
¶
current view matrix, this will be the default for next rendering
proj = proj
instance-attribute
¶
current projection matrix, this will be the default for next rendering
enable_ident = enable_ident
instance-attribute
¶
enable self.ident
enable_alpha = enable_alpha
instance-attribute
¶
render(size=None, view=None, proj=None)
¶
trigger the rendering of a frame, do not wait for the result
- the
viewandprojinstance attributes can be changed on the fly without extra cost. - a
sizechange will trigger reallocation of the buffers
Source code in madcad/rendering/d3/view.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | |
identstep(nidents)
¶
Updates the amount of rendered idents and return the start ident for the calling rendering pass? Method to call during a renderstep
Source code in madcad/rendering/d3/view.py
136 137 138 139 140 141 142 143 144 | |
Offscreen3D(scene, size=None, view=None, proj=None, enable_depth=False, enable_ident=False, enable_alpha=False, **uniforms)
¶
3D view giving images accessible to numpy buffers
Source code in madcad/rendering/d3/view.py
171 172 173 174 175 176 177 178 179 180 | |
gl = GLView3D(scene, size, view, proj, enable_ident, enable_alpha, **uniforms)
instance-attribute
¶
opengl renderer
color = None
instance-attribute
¶
result image from the previous rendering, showing the
depth = None
instance-attribute
¶
result image from the previous rendering, showing the
ident = None
instance-attribute
¶
result image from the previous rendering, showing the
enable_alpha = forwardproperty('gl', 'enable_alpha')
class-attribute
instance-attribute
¶
if enabled, self.color is RGBA else it is 'RGB'
enable_depth = enable_depth
instance-attribute
¶
enable self.depth
enable_ident = forwardproperty('gl', 'enable_ident')
class-attribute
instance-attribute
¶
enable self.ident
scene = forwardproperty('gl', 'scene')
class-attribute
instance-attribute
¶
view = forwardproperty('gl', 'view')
class-attribute
instance-attribute
¶
proj = forwardproperty('gl', 'proj')
class-attribute
instance-attribute
¶
uniforms = forwardproperty('gl', 'uniforms')
class-attribute
instance-attribute
¶
render(size=None, view=None, proj=None)
¶
render the scene and retreive the result in the color, depth and ident attributes
- the
viewandprojinstance attributes can be changed on the fly without extra cost. - a
sizechange will trigger reallocation of the buffers
Source code in madcad/rendering/d3/view.py
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | |
View projections and navigation¶
Turntable(position=0, distance=1, yaw=0, pitch=0)
¶
Navigation rotating on yaw and pitch around a center
Object used as View.navigation
Source code in madcad/rendering/d3/view.py
753 754 755 756 757 | |
position = fvec3(position)
instance-attribute
¶
distance = distance
instance-attribute
¶
pitch = pitch
instance-attribute
¶
yaw = yaw
instance-attribute
¶
matrix()
¶
Source code in madcad/rendering/d3/view.py
759 760 761 762 763 764 | |
adjust(distance)
¶
Source code in madcad/rendering/d3/view.py
766 767 | |
look(position)
¶
Source code in madcad/rendering/d3/view.py
769 770 771 772 773 | |
sight(direction)
¶
Source code in madcad/rendering/d3/view.py
775 776 777 778 779 | |
center(position)
¶
Source code in madcad/rendering/d3/view.py
781 782 | |
zoom(ratio)
¶
Source code in madcad/rendering/d3/view.py
784 785 | |
pan(offset)
¶
Source code in madcad/rendering/d3/view.py
787 788 789 | |
rotate(offset)
¶
Source code in madcad/rendering/d3/view.py
791 792 793 794 795 796 | |
Orbit(position=0, distance=1, orientation=fquat())
¶
Navigation rotating on the 3 axis around a center.
Object used as View.navigation
Source code in madcad/rendering/d3/view.py
704 705 706 707 | |
position = fvec3(position)
instance-attribute
¶
distance = float(distance)
instance-attribute
¶
orientation = fquat(orientation)
instance-attribute
¶
matrix()
¶
Source code in madcad/rendering/d3/view.py
709 710 711 712 | |
adjust(distance)
¶
Source code in madcad/rendering/d3/view.py
714 715 | |
look(position)
¶
Source code in madcad/rendering/d3/view.py
717 718 719 720 721 | |
sight(direction)
¶
Source code in madcad/rendering/d3/view.py
723 724 725 726 727 | |
center(position)
¶
Source code in madcad/rendering/d3/view.py
729 730 | |
zoom(ratio)
¶
Source code in madcad/rendering/d3/view.py
732 733 | |
pan(offset)
¶
Source code in madcad/rendering/d3/view.py
735 736 737 | |
rotate(offset)
¶
Source code in madcad/rendering/d3/view.py
739 740 741 | |
Perspective(fov=None)
¶
Object used as View.projection
Attributes:
| Name | Type | Description |
|---|---|---|
fov |
float
|
field of view (rad), defaulting to |
Source code in madcad/rendering/d3/view.py
806 807 | |
fov = fov or settings.display['field_of_view']
instance-attribute
¶
matrix(ratio, distance)
¶
Source code in madcad/rendering/d3/view.py
809 810 | |
adjust(size)
¶
Source code in madcad/rendering/d3/view.py
812 813 | |
Orthographic(size=None)
¶
Object used as View.projection
Attributes:
| Name | Type | Description |
|---|---|---|
size |
float
|
factor between the distance from camera to navigation center and the zone size to display
defaulting to |
Source code in madcad/rendering/d3/view.py
824 825 | |
size = size or tan(settings.display['field_of_view'] / 2)
instance-attribute
¶
matrix(ratio, distance)
¶
Source code in madcad/rendering/d3/view.py
827 828 829 830 831 832 833 | |
adjust(size)
¶
Source code in madcad/rendering/d3/view.py
835 836 | |
Helpers to trick into the pipeline¶
Group(scene, src=None, world=1)
¶
Bases: Display
display holding multiple displays associated with a key, just like a dictionnary
world, selected, hovered properties are propagated to its children
Source code in madcad/rendering/base.py
405 406 407 408 409 410 411 412 | |
box
property
¶
stack(scene)
¶
Source code in madcad/rendering/base.py
484 485 486 487 488 489 | |
__getitem__(key)
¶
Source code in madcad/rendering/base.py
494 495 | |
update(*args)
¶
update(scene, src)
update(src)
update all child displays with the displayable present in the given dictionnary
former children that do not match keys in the given dictionnary are dropped
Note
the new content will not be immediately available in self.displays because they will only be buffered at next rendering. it makes this function thread safe and able to run without a reference to the scene
Source code in madcad/rendering/base.py
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | |
world()
¶
Source code in madcad/rendering/base.py
420 421 422 423 | |
Step(display, target, priority, render)
dataclass
¶
describes a rendering step for a display
display
instance-attribute
¶
the display instance responsible of this callback
target
instance-attribute
¶
the name of the render target in the view that will be rendered (see View)
priority
instance-attribute
¶
a float that is used to insert the callable at the proper place in the rendering stack
render
instance-attribute
¶
a function that renders, signature is func(view)
Displayable(build, *args, **kwargs)
¶
Simple displayable initializing the given Display class with arguments
At the display creation time, it will simply execute build(*args, **kwargs)
Source code in madcad/rendering/base.py
513 514 515 | |
__slots__ = ('build', 'args', 'kwargs')
class-attribute
instance-attribute
¶
build = build
instance-attribute
¶
__eq__(other)
¶
Source code in madcad/rendering/base.py
516 517 518 519 520 521 | |
__repr__()
¶
Source code in madcad/rendering/base.py
522 523 524 525 526 527 | |
display(scene)
¶
Source code in madcad/rendering/base.py
528 529 | |