Skip to content

settings -- Global and default settings

Quick configuration

You can customize madcad with settings. You simply start to write a configuration file, then madcad does the rest for you.

import madcad
madcad.settings.install() # it will create a file in ~/.config/madcad/pymadcad.yaml

Now, you can edit the file ~/.config/madcad/pymadcad.yaml:

controls: {navigation: Turntable, snap_dist: 10}
display:
    annotation_color: [0.2, 0.7, 1.0]
    background_color: [0.0, 0.0, 0.0]
    field_of_view: 0.5235987755982988
    highlight_color: [0.1, 0.2, 0.2]
    line_color: [0.9, 0.9, 0.9]
    line_width: 1.0
    point_color: [0.9, 0.9, 0.9]
    schematics_color: [0.3, 0.8, 1.0]
    select_color_face: [0.01, 0.05, 0.03]
    select_color_line: [0.5, 1.0, 0.6]
    sharp_angle: 0.5235987755982988
    solid_color: [0.2, 0.2, 0.2]
    solid_color_front: 1.0
    solid_color_side: 0.2
    solid_reflect: skybox-white.png
    solid_reflectivity: 6
    solver_error_color: [1.0, 0.3, 0.2]
    system_theme: true
    view_font_size: 8
primitives:
    curve_resolution: [rad, 0.19634954084936207]
scene: {debug_faces: false, debug_groups: false,
    debug_points: false, display_annotations: true,
    display_faces: true, display_grid: true,
    display_groups: true, display_points: false,
    display_wire: false, lock_solids: true,
    projection: Perspective, surface_shading: true}

Note

Values of colors are going from 0 to 1.

If you want, you can change this configuration folder by using:

import madcad
myfile = open("myfile.yaml", "w")
madcad.settings.dump(myfile)

Then, in your script, load it:

from madcad import *

myfile = open("myfile.yaml")
settings.load(myfile)
mesh = screw(10, 20)
show([mesh])

Module

The settings module holds dictionaries each aspect of the madcad library.

dictionaries

:primitives: default settings for mesh and primitive operations :display: visual settings to display the 3D objects :scene: for what and how to display in the 3D scene :controls: preferences for the controls of the Scene widget

All the settings presents here are loaded at start or on demand from ~/.config/madcad/pymadcad.json

load(file=None)

Load the settings directly in this module, from the specified file or the default one

Source code in madcad/settings.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
def load(file=None):
	''' Load the settings directly in this module, from the specified file or the default one '''
	if not file:	file = config
	if isinstance(file, str):	file = open(file, 'r')
	changes = yaml.safe_load(file)
	def update(dst, src):
		for key in dst:
			if key in src:
				if isinstance(dst[key], dict) and isinstance(src[key], dict):	
					update(dst[key], src[key])
				elif isinstance(dst[key], fvec3):	dst[key] = fvec3(src[key])
				elif isinstance(dst[key], fvec4):	dst[key] = fvec4(src[key])
				else:
					dst[key] = src[key]
	update(settings, changes)

dump(file=None)

Load the current settings into the specified file or to the default one

Source code in madcad/settings.py
137
138
139
140
141
142
143
def dump(file=None):
	''' Load the current settings into the specified file or to the default one '''
	if not file:	file = config
	if isinstance(file, str):	file = open(file, 'w')
	yaml.add_representer(fvec3, lambda dumper, data: dumper.represent_list(round(f,3) for f in data))
	yaml.add_representer(fvec4, lambda dumper, data: dumper.represent_list(round(f,3) for f in data))
	file.write(yaml.dump(settings, default_flow_style=None, width=40, indent=4))

install()

Create and fill the config directory if not already existing

Source code in madcad/settings.py
111
112
113
114
115
def install():
	''' Create and fill the config directory if not already existing '''
	if not exists(config):
		os.makedirs(dirname(config), exist_ok=True)
		dump()

clean()

Delete the default configuration file

Source code in madcad/settings.py
117
118
119
def clean():
	''' Delete the default configuration file '''
	os.rm(config)

use_qt_colors()

Set the color settings to fit the current system colors

Source code in madcad/settings.py
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
def use_qt_colors():
	''' Set the color settings to fit the current system colors '''
	from .mathutils import fvec3, mix, distance
	from .qt import QApplication, QPalette
	role = QPalette.ColorRole
	palette = QApplication.instance().palette()
	def qtc(role):
		''' Convert a QColor or QPalette role to fvec3'''
		c = palette.color(role)
		return fvec3(c.red(), c.green(), c.blue()) / 255

	selection = mix(fvec3(0.4, 1, 0), qtc(role.Highlight), 0.6)
	selection *= mix(1/max(selection), max(qtc(role.Text)), 0.3)
	hover = mix(fvec3(0., 0.4, 1), qtc(role.Highlight), 0.3)
	hover *= mix(1/max(selection), max(qtc(role.Text)), 0.3)
	display.update({
		'background_color': qtc(role.Window),
		'selection_color': fvec4(selection, 1),
		'hover_color': fvec4(hover, 0.7),
		})
	colors.update({
		'line': qtc(role.Text),
		'point': qtc(role.Text),
		'surface': mix(qtc(role.Text), qtc(role.Window), 0.7),
		'schematic': mix(qtc(role.Text)*normalize(qtc(role.LinkVisited)+0.01), qtc(role.LinkVisited), 0.5),
		'annotation': mix(qtc(role.Text)*normalize(qtc(role.Link)+0.01), qtc(role.Link), 0.5),
		})

curve_resolution(length, angle, param=None)

Return the subdivision number for a curve, using the given or setting specification

:length: is the curvilign length of the curve :angle: is the integral of the absolute curvature (total rotation angle)

Source code in madcad/settings.py
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
def curve_resolution(length, angle, param=None):
	''' Return the subdivision number for a curve, using the given or setting specification

		:length:  is the curvilign length of the curve
		:angle:   is the integral of the absolute curvature (total rotation angle)
	'''
	kind, prec = param or resolution
	if kind == 'div':
		res = prec
	elif kind == 'm':
		res = ceil(length / prec)
	elif kind == 'rad':
		res = floor(angle / prec)
	elif kind == 'radm':
		res = floor(length*angle / prec)
	elif kind == 'sqradm':
		res = floor(sqrt(length*angle) / prec)
	else:
		raise ValueError("unknown type for round_limit: {}".format(repr(kind)))
	res = max(res, floor(angle * 2/pi))
	return res