Merged 15170:15635 from trunk (no conflicts or even merges)
This commit is contained in:
@@ -229,13 +229,6 @@ void BPY_start_python( int argc, char **argv )
|
||||
/* Initialize thread support (also acquires lock) */
|
||||
PyEval_InitThreads();
|
||||
|
||||
/* Don't allow the Python Interpreter to release the GIL on
|
||||
* its own, to guarantee PyNodes work properly. For Blender this
|
||||
* is currently the best default behavior.
|
||||
* The following code in C is equivalent in Python to:
|
||||
* "import sys; sys.setcheckinterval(sys.maxint)" */
|
||||
_Py_CheckInterval = PyInt_GetMax();
|
||||
|
||||
//Overrides __import__
|
||||
init_ourImport( );
|
||||
init_ourReload( );
|
||||
@@ -1183,13 +1176,17 @@ static void unlink_script( Script * script )
|
||||
if( sl->spacetype == SPACE_SCRIPT ) {
|
||||
SpaceScript *sc = ( SpaceScript * ) sl;
|
||||
|
||||
if( sc->script == script ) {
|
||||
if( sc->script == script ) {
|
||||
sc->script = NULL;
|
||||
|
||||
if( sc ==
|
||||
area->spacedata.first ) {
|
||||
scrarea_queue_redraw
|
||||
( area );
|
||||
if( sc == area->spacedata.first ) {
|
||||
scrarea_queue_redraw( area );
|
||||
}
|
||||
|
||||
if (sc->but_refs) {
|
||||
BPy_Set_DrawButtonsList(sc->but_refs);
|
||||
BPy_Free_DrawButtonsList();
|
||||
sc->but_refs = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2213,6 +2210,18 @@ void BPY_do_all_scripts( short event )
|
||||
|
||||
BPY_do_pyscript( &( G.scene->id ), event );
|
||||
|
||||
/* Don't allow the Python Interpreter to release the GIL on
|
||||
* its own, to guarantee PyNodes work properly. For Blender this
|
||||
* is currently the best default behavior.
|
||||
* The following code in C is equivalent in Python to:
|
||||
* "import sys; sys.setcheckinterval(sys.maxint)" */
|
||||
if (event == SCRIPT_RENDER) {
|
||||
_Py_CheckInterval = PyInt_GetMax();
|
||||
}
|
||||
else if (event == SCRIPT_POSTRENDER) {
|
||||
_Py_CheckInterval = 100; /* Python default */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2295,9 +2304,9 @@ void BPY_do_pyscript( ID * id, short event )
|
||||
return;
|
||||
}
|
||||
|
||||
/* tell we're running a scriptlink. The sum also tells if this script
|
||||
* is running nested inside another. Blender.Load needs this info to
|
||||
* avoid trouble with invalid slink pointers. */
|
||||
/* tell we're running a scriptlink. The sum also tells if this
|
||||
* script is running nested inside another. Blender.Load needs
|
||||
* this info to avoid trouble with invalid slink pointers. */
|
||||
during_slink++;
|
||||
disable_where_scriptlink( (short)during_slink );
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@ static int CurNurb_setFlagU( BPy_CurNurb * self, PyObject * args );
|
||||
static PyObject *CurNurb_getFlagV( BPy_CurNurb * self );
|
||||
static PyObject *CurNurb_oldsetFlagV( BPy_CurNurb * self, PyObject * args );
|
||||
static int CurNurb_setFlagV( BPy_CurNurb * self, PyObject * args );
|
||||
static PyObject *CurNurb_getOrderU( BPy_CurNurb * self );
|
||||
static int CurNurb_setOrderU( BPy_CurNurb * self, PyObject * args );
|
||||
static PyObject *CurNurb_getType( BPy_CurNurb * self );
|
||||
static PyObject *CurNurb_oldsetType( BPy_CurNurb * self, PyObject * args );
|
||||
static int CurNurb_setType( BPy_CurNurb * self, PyObject * args );
|
||||
@@ -176,6 +178,9 @@ static PyGetSetDef BPy_CurNurb_getseters[] = {
|
||||
(getter)CurNurb_getFlagV, (setter)CurNurb_setFlagV,
|
||||
"The knot type in the V direction",
|
||||
NULL},
|
||||
{"orderU",
|
||||
(getter)CurNurb_getOrderU, (setter)CurNurb_setOrderU,
|
||||
"order setting for U direction", NULL},
|
||||
{"type",
|
||||
(getter)CurNurb_getType, (setter)CurNurb_setType,
|
||||
"The curve type (poly: bezier, or NURBS)",
|
||||
@@ -710,6 +715,35 @@ static int CurNurb_setFlagV( BPy_CurNurb * self, PyObject * args )
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *CurNurb_getOrderU( BPy_CurNurb * self )
|
||||
{
|
||||
return PyInt_FromLong( ( long ) self->nurb->orderu );
|
||||
}
|
||||
|
||||
static int CurNurb_setOrderU( BPy_CurNurb * self, PyObject * args )
|
||||
{
|
||||
int order;
|
||||
|
||||
args = PyNumber_Int( args );
|
||||
if( !args )
|
||||
return EXPP_ReturnIntError( PyExc_TypeError,
|
||||
"expected integer argument" );
|
||||
|
||||
order = ( int )PyInt_AS_LONG( args );
|
||||
Py_DECREF( args );
|
||||
|
||||
if( order < 2 ) order = 2;
|
||||
else if( order > 6 ) order = 6;
|
||||
|
||||
if( self->nurb->pntsu < order )
|
||||
order = self->nurb->pntsu;
|
||||
|
||||
self->nurb->orderu = (short)order;
|
||||
makeknots( self->nurb, 1, self->nurb->flagu >> 1 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* CurNurb_getIter
|
||||
*
|
||||
|
||||
@@ -1520,12 +1520,11 @@ static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value )
|
||||
char *type = PyString_AsString(value);
|
||||
PyObject *arg, *error;
|
||||
|
||||
/* parse string argument */
|
||||
|
||||
if( !value )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"expected string argument" ) );
|
||||
|
||||
/* parse string argument */
|
||||
if( !type )
|
||||
return EXPP_ReturnPyObjError ( PyExc_TypeError,
|
||||
"expected string argument" );
|
||||
|
||||
/* check for valid arguments, set type accordingly */
|
||||
|
||||
if( !strcmp( type, "Lamp" ) )
|
||||
@@ -1546,7 +1545,7 @@ static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value )
|
||||
|
||||
/* build tuple, call wrapper */
|
||||
|
||||
arg = Py_BuildValue( "(i)", type );
|
||||
arg = Py_BuildValue( "(i)", self->lamp->type );
|
||||
error = EXPP_setterWrapper ( (void *)self, arg, (setter)Lamp_setType );
|
||||
Py_DECREF ( arg );
|
||||
return error;
|
||||
|
||||
@@ -725,28 +725,33 @@ PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
|
||||
vec->vec[0] /= norm;
|
||||
vec->vec[1] /= norm;
|
||||
vec->vec[2] /= norm;
|
||||
|
||||
//create matrix
|
||||
cosAngle = (float) cos(angle);
|
||||
sinAngle = (float) sin(angle);
|
||||
mat[0] = ((vec->vec[0] * vec->vec[0]) * (1 - cosAngle)) +
|
||||
cosAngle;
|
||||
mat[1] = ((vec->vec[0] * vec->vec[1]) * (1 - cosAngle)) +
|
||||
(vec->vec[2] * sinAngle);
|
||||
mat[2] = ((vec->vec[0] * vec->vec[2]) * (1 - cosAngle)) -
|
||||
(vec->vec[1] * sinAngle);
|
||||
mat[3] = ((vec->vec[0] * vec->vec[1]) * (1 - cosAngle)) -
|
||||
(vec->vec[2] * sinAngle);
|
||||
mat[4] = ((vec->vec[1] * vec->vec[1]) * (1 - cosAngle)) +
|
||||
cosAngle;
|
||||
mat[5] = ((vec->vec[1] * vec->vec[2]) * (1 - cosAngle)) +
|
||||
(vec->vec[0] * sinAngle);
|
||||
mat[6] = ((vec->vec[0] * vec->vec[2]) * (1 - cosAngle)) +
|
||||
(vec->vec[1] * sinAngle);
|
||||
mat[7] = ((vec->vec[1] * vec->vec[2]) * (1 - cosAngle)) -
|
||||
(vec->vec[0] * sinAngle);
|
||||
mat[8] = ((vec->vec[2] * vec->vec[2]) * (1 - cosAngle)) +
|
||||
cosAngle;
|
||||
|
||||
if (isnan(vec->vec[0]) || isnan(vec->vec[1]) || isnan(vec->vec[2])) {
|
||||
/* zero length vector, return an identity matrix, could also return an error */
|
||||
mat[0]= mat[4] = mat[8] = 1.0f;
|
||||
} else {
|
||||
/* create matrix */
|
||||
cosAngle = (float) cos(angle);
|
||||
sinAngle = (float) sin(angle);
|
||||
mat[0] = ((vec->vec[0] * vec->vec[0]) * (1 - cosAngle)) +
|
||||
cosAngle;
|
||||
mat[1] = ((vec->vec[0] * vec->vec[1]) * (1 - cosAngle)) +
|
||||
(vec->vec[2] * sinAngle);
|
||||
mat[2] = ((vec->vec[0] * vec->vec[2]) * (1 - cosAngle)) -
|
||||
(vec->vec[1] * sinAngle);
|
||||
mat[3] = ((vec->vec[0] * vec->vec[1]) * (1 - cosAngle)) -
|
||||
(vec->vec[2] * sinAngle);
|
||||
mat[4] = ((vec->vec[1] * vec->vec[1]) * (1 - cosAngle)) +
|
||||
cosAngle;
|
||||
mat[5] = ((vec->vec[1] * vec->vec[2]) * (1 - cosAngle)) +
|
||||
(vec->vec[0] * sinAngle);
|
||||
mat[6] = ((vec->vec[0] * vec->vec[2]) * (1 - cosAngle)) +
|
||||
(vec->vec[1] * sinAngle);
|
||||
mat[7] = ((vec->vec[1] * vec->vec[2]) * (1 - cosAngle)) -
|
||||
(vec->vec[0] * sinAngle);
|
||||
mat[8] = ((vec->vec[2] * vec->vec[2]) * (1 - cosAngle)) +
|
||||
cosAngle;
|
||||
}
|
||||
} else {
|
||||
return EXPP_ReturnPyObjError(PyExc_AttributeError,
|
||||
"Mathutils.RotationMatrix(): unrecognizable axis of rotation type - expected x,y,z or r\n");
|
||||
@@ -1447,8 +1452,8 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
|
||||
"vectors must be of the same size\n" ) );
|
||||
|
||||
if( vec1->size == 3 || vec1->size == 2) {
|
||||
float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3];
|
||||
float d;
|
||||
int result;
|
||||
|
||||
if (vec1->size == 3) {
|
||||
VECCOPY(v1, vec1->vec);
|
||||
VECCOPY(v2, vec2->vec);
|
||||
@@ -1472,63 +1477,19 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
|
||||
v4[1] = vec4->vec[1];
|
||||
v4[2] = 0.0f;
|
||||
}
|
||||
|
||||
result = LineIntersectLine(v1, v2, v3, v4, i1, i2);
|
||||
|
||||
VecSubf(c, v3, v1);
|
||||
VecSubf(a, v2, v1);
|
||||
VecSubf(b, v4, v3);
|
||||
|
||||
VECCOPY(dir1, a);
|
||||
Normalize(dir1);
|
||||
VECCOPY(dir2, b);
|
||||
Normalize(dir2);
|
||||
d = Inpf(dir1, dir2);
|
||||
if (d == 1.0f || d == -1.0f) {
|
||||
if (result == 0) {
|
||||
/* colinear */
|
||||
return EXPP_incr_ret( Py_None );
|
||||
}
|
||||
|
||||
Crossf(ab, a, b);
|
||||
d = Inpf(c, ab);
|
||||
|
||||
/* test if the two lines are coplanar */
|
||||
if (d > -0.000001f && d < 0.000001f) {
|
||||
Crossf(cb, c, b);
|
||||
|
||||
VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
|
||||
VecAddf(i1, v1, a);
|
||||
VECCOPY(i2, i1);
|
||||
}
|
||||
/* if not */
|
||||
else {
|
||||
float n[3], t[3];
|
||||
VecSubf(t, v1, v3);
|
||||
|
||||
/* offset between both plane where the lines lies */
|
||||
Crossf(n, a, b);
|
||||
Projf(t, t, n);
|
||||
|
||||
/* for the first line, offset the second line until it is coplanar */
|
||||
VecAddf(v3, v3, t);
|
||||
VecAddf(v4, v4, t);
|
||||
|
||||
VecSubf(c, v3, v1);
|
||||
VecSubf(a, v2, v1);
|
||||
VecSubf(b, v4, v3);
|
||||
|
||||
Crossf(ab, a, b);
|
||||
Crossf(cb, c, b);
|
||||
|
||||
VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
|
||||
VecAddf(i1, v1, a);
|
||||
|
||||
/* for the second line, just substract the offset from the first intersection point */
|
||||
VecSubf(i2, i1, t);
|
||||
tuple = PyTuple_New( 2 );
|
||||
PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) );
|
||||
PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) );
|
||||
return tuple;
|
||||
}
|
||||
|
||||
tuple = PyTuple_New( 2 );
|
||||
PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) );
|
||||
PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) );
|
||||
return tuple;
|
||||
}
|
||||
else {
|
||||
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
|
||||
@@ -535,6 +535,8 @@ class CurNurb:
|
||||
@type flagU: int
|
||||
@ivar flagV: The CurNurb knot flag V. See L{setFlagU} for description.
|
||||
@type flagV: int
|
||||
@ivar orderU: The CurNurb knot order U, for nurbs curves only, this is clamped by the number of points, so the orderU will never be greater.
|
||||
@type orderU: int
|
||||
@ivar type: The type of the curve (Poly: 0, Bezier: 1, NURBS: 4)
|
||||
@type type: int
|
||||
@ivar knotsU: The knot vector in the U direction. The tuple will be empty
|
||||
|
||||
@@ -833,9 +833,7 @@ class RenderData:
|
||||
|
||||
def enableCropping(toggle):
|
||||
"""
|
||||
Enable/disable exclusion of border rendering from total image.
|
||||
@type toggle: int
|
||||
@param toggle: pass 1 for on / 0 for off
|
||||
Deprecated: see the L{crop} attribute.
|
||||
"""
|
||||
|
||||
def setImageType(type):
|
||||
|
||||
@@ -483,7 +483,7 @@ static char MatrixObject_doc[] = "This is a wrapper for matrix objects.";
|
||||
sequence length*/
|
||||
static int Matrix_len(MatrixObject * self)
|
||||
{
|
||||
return (self->colSize * self->rowSize);
|
||||
return (self->rowSize);
|
||||
}
|
||||
/*----------------------------object[]---------------------------
|
||||
sequence accessor (get)
|
||||
|
||||
@@ -985,7 +985,7 @@ PyObject *RenderData_EnableCropping( void )
|
||||
/* return M_Render_BitToggleInt( args, R_MOVIECROP,
|
||||
&self->renderContext->mode );
|
||||
*/
|
||||
printf("cropping option is now default, obsolete\n");
|
||||
printf("obsolete: movie cropping option is now default\n");
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ returns None if notfound.\nIf 'name' is not specified, it returns a list of all
|
||||
static PyObject *Sequence_copy( BPy_Sequence * self );
|
||||
static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args );
|
||||
static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args );
|
||||
static PyObject *Sequence_rebuildProxy( BPy_Sequence * self );
|
||||
|
||||
static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args );
|
||||
static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args );
|
||||
@@ -96,6 +97,8 @@ static PyMethodDef BPy_Sequence_methods[] = {
|
||||
"() - Return a copy of the sequence containing the same objects."},
|
||||
{"copy", ( PyCFunction ) Sequence_copy, METH_NOARGS,
|
||||
"() - Return a copy of the sequence containing the same objects."},
|
||||
{"rebuildProxy", ( PyCFunction ) Sequence_rebuildProxy, METH_VARARGS,
|
||||
"() - Rebuild the active strip's Proxy."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -309,6 +312,7 @@ static PyObject *Sequence_copy( BPy_Sequence * self )
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* PythonTypeObject callback function prototypes */
|
||||
/*****************************************************************************/
|
||||
@@ -383,8 +387,6 @@ static PyObject *SceneSeq_nextIter( BPy_Sequence * self )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static PyObject *Sequence_getName( BPy_Sequence * self )
|
||||
{
|
||||
return PyString_FromString( self->seq->name+2 );
|
||||
@@ -403,11 +405,13 @@ static int Sequence_setName( BPy_Sequence * self, PyObject * value )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *Sequence_getProxyDir( BPy_Sequence * self )
|
||||
{
|
||||
return PyString_FromString( self->seq->strip->proxy ? self->seq->strip->proxy->dir : "" );
|
||||
}
|
||||
|
||||
|
||||
static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value )
|
||||
{
|
||||
char *name = NULL;
|
||||
@@ -430,6 +434,14 @@ static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value )
|
||||
}
|
||||
|
||||
|
||||
static PyObject *Sequence_rebuildProxy( BPy_Sequence * self )
|
||||
{
|
||||
if (self->seq->strip->proxy)
|
||||
seq_proxy_rebuild(self->seq);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *Sequence_getSound( BPy_Sequence * self )
|
||||
{
|
||||
if (self->seq->type == SEQ_RAM_SOUND && self->seq->sound)
|
||||
@@ -622,6 +634,54 @@ static int Sequence_setImages( BPy_Sequence * self, PyObject *value )
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *M_Sequence_BlendModesDict( void )
|
||||
{
|
||||
PyObject *M = PyConstant_New( );
|
||||
|
||||
if( M ) {
|
||||
BPy_constant *d = ( BPy_constant * ) M;
|
||||
PyConstant_Insert( d, "CROSS", PyInt_FromLong( SEQ_CROSS ) );
|
||||
PyConstant_Insert( d, "ADD", PyInt_FromLong( SEQ_ADD ) );
|
||||
PyConstant_Insert( d, "SUBTRACT", PyInt_FromLong( SEQ_SUB ) );
|
||||
PyConstant_Insert( d, "ALPHAOVER", PyInt_FromLong( SEQ_ALPHAOVER ) );
|
||||
PyConstant_Insert( d, "ALPHAUNDER", PyInt_FromLong( SEQ_ALPHAUNDER ) );
|
||||
PyConstant_Insert( d, "GAMMACROSS", PyInt_FromLong( SEQ_GAMCROSS ) );
|
||||
PyConstant_Insert( d, "MULTIPLY", PyInt_FromLong( SEQ_MUL ) );
|
||||
PyConstant_Insert( d, "OVERDROP", PyInt_FromLong( SEQ_OVERDROP ) );
|
||||
PyConstant_Insert( d, "PLUGIN", PyInt_FromLong( SEQ_PLUGIN ) );
|
||||
PyConstant_Insert( d, "WIPE", PyInt_FromLong( SEQ_WIPE ) );
|
||||
PyConstant_Insert( d, "GLOW", PyInt_FromLong( SEQ_GLOW ) );
|
||||
PyConstant_Insert( d, "TRANSFORM", PyInt_FromLong( SEQ_TRANSFORM ) );
|
||||
PyConstant_Insert( d, "COLOR", PyInt_FromLong( SEQ_COLOR ) );
|
||||
PyConstant_Insert( d, "SPEED", PyInt_FromLong( SEQ_SPEED ) );
|
||||
}
|
||||
return M;
|
||||
}
|
||||
|
||||
static PyObject *Sequence_getBlendMode( BPy_Sequence * self )
|
||||
{
|
||||
return PyInt_FromLong( self->seq->blend_mode );
|
||||
}
|
||||
|
||||
static int Sequence_setBlendMode( BPy_Sequence * self, PyObject * value )
|
||||
{
|
||||
struct Sequence *seq= self->seq;
|
||||
int number = PyInt_AsLong( value );
|
||||
|
||||
if( number==-1 && PyErr_Occurred() )
|
||||
return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
|
||||
|
||||
if ( !seq_can_blend(seq) )
|
||||
return EXPP_ReturnIntError( PyExc_AttributeError, "this sequence type dosnt support blending" );
|
||||
|
||||
if (number<SEQ_EFFECT || number>SEQ_EFFECT_MAX)
|
||||
return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
|
||||
|
||||
seq->blend_mode=number;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* get floating point attributes
|
||||
*/
|
||||
@@ -836,7 +896,11 @@ static PyGetSetDef BPy_Sequence_getseters[] = {
|
||||
(getter)Sequence_getImages, (setter)Sequence_setImages,
|
||||
"Sequence scene",
|
||||
NULL},
|
||||
|
||||
{"blendMode",
|
||||
(getter)Sequence_getBlendMode, (setter)Sequence_setBlendMode,
|
||||
"Sequence Blend Mode",
|
||||
NULL},
|
||||
|
||||
{"type",
|
||||
(getter)getIntAttr, (setter)NULL,
|
||||
"",
|
||||
@@ -1131,6 +1195,7 @@ PyObject *M_Sequence_Get( PyObject * self, PyObject * args )
|
||||
/*****************************************************************************/
|
||||
PyObject *Sequence_Init( void )
|
||||
{
|
||||
PyObject *BlendModesDict = M_Sequence_BlendModesDict( );
|
||||
PyObject *submodule;
|
||||
if( PyType_Ready( &Sequence_Type ) < 0 )
|
||||
return NULL;
|
||||
@@ -1142,6 +1207,9 @@ PyObject *Sequence_Init( void )
|
||||
"The Blender Sequence module\n\n\
|
||||
This module provides access to **Sequence Data** in Blender.\n" );
|
||||
|
||||
if( BlendModesDict )
|
||||
PyModule_AddObject( submodule, "BlendModes", BlendModesDict );
|
||||
|
||||
/*Add SUBMODULES to the module*/
|
||||
/*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/
|
||||
return submodule;
|
||||
|
||||
Reference in New Issue
Block a user