struct lhsParseNode *RestrictionParse( char *readSource, struct token *theToken, int multifieldSlot, struct symbolHashNode *theSlot, int slotNumber, CONSTRAINT_RECORD *theConstraints, int position) { struct lhsParseNode *topNode = NULL, *lastNode = NULL, *nextNode; int numberOfSingleFields = 0; int numberOfMultifields = 0; int startPosition = position; int error = FALSE; CONSTRAINT_RECORD *tempConstraints; /*==================================================*/ /* Keep parsing fields until a right parenthesis is */ /* encountered. This will either indicate the end */ /* of an instance or deftemplate slot or the end of */ /* an ordered fact. */ /*==================================================*/ while (theToken->type != RPAREN) { /*========================================*/ /* Look for either a single or multifield */ /* wildcard or a conjuctive restriction. */ /*========================================*/ if ((theToken->type == SF_WILDCARD) || (theToken->type == MF_WILDCARD)) { nextNode = GetLHSParseNode(); nextNode->type = theToken->type; nextNode->negated = FALSE; GetToken(readSource,theToken); } else { #if FUZZY_DEFTEMPLATES nextNode = ConjuctiveRestrictionParse(readSource,theToken,&error,theConstraints); #else nextNode = ConjuctiveRestrictionParse(readSource,theToken,&error); #endif if (nextNode == NULL) { ReturnLHSParseNodes(topNode); return(NULL); } } /*========================================================*/ /* Fix up the pretty print representation of a multifield */ /* slot so that the fields don't run together. */ /*========================================================*/ if ((theToken->type != RPAREN) && (multifieldSlot == TRUE)) { PPBackup(); SavePPBuffer(" "); SavePPBuffer(theToken->printForm); } /*========================================*/ /* Keep track of the number of single and */ /* multifield restrictions encountered. */ /*========================================*/ if ((nextNode->type == SF_WILDCARD) || (nextNode->type == SF_VARIABLE)) { numberOfSingleFields++; } else { numberOfMultifields++; } /*===================================*/ /* Assign the slot name and indices. */ /*===================================*/ nextNode->slot = theSlot; nextNode->slotNumber = slotNumber; nextNode->index = position++; /*==============================================*/ /* If we're not dealing with a multifield slot, */ /* attach the constraints directly to the node */ /* and return. */ /*==============================================*/ if (! multifieldSlot) { if (theConstraints == NULL) { if (nextNode->type == SF_VARIABLE) { nextNode->constraints = GetConstraintRecord(); } else nextNode->constraints = NULL; } else nextNode->constraints = theConstraints; return(nextNode); } /*====================================================*/ /* Attach the restriction to the list of restrictions */ /* already parsed for this slot or ordered fact. */ /*====================================================*/ if (lastNode == NULL) topNode = nextNode; else lastNode->right = nextNode; lastNode = nextNode; } /*=====================================================*/ /* Once we're through parsing, check to make sure that */ /* a single field slot was given a restriction. If the */ /* following test fails, then we know we're dealing */ /* with a multifield slot. */ /*=====================================================*/ if ((topNode == NULL) && (! multifieldSlot)) { SyntaxErrorMessage("defrule"); return(NULL); } /*===============================================*/ /* Loop through each of the restrictions in the */ /* list of restrictions for the multifield slot. */ /*===============================================*/ for (nextNode = topNode; nextNode != NULL; nextNode = nextNode->right) { /*===================================================*/ /* Assign a constraint record to each constraint. If */ /* the slot has an explicit constraint, then copy */ /* this and store it with the constraint. Otherwise, */ /* create a constraint record for a single field */ /* constraint and skip the constraint modifications */ /* for a multifield constraint. */ /*===================================================*/ if (theConstraints == NULL) { if (nextNode->type == SF_VARIABLE) { nextNode->constraints = GetConstraintRecord(); } else { continue; } } else { nextNode->constraints = CopyConstraintRecord(theConstraints); } /*==========================================*/ /* Remove the min and max field constraints */ /* for the entire slot from the constraint */ /* record for this single constraint. */ /*==========================================*/ ReturnExpression(nextNode->constraints->minFields); ReturnExpression(nextNode->constraints->maxFields); nextNode->constraints->minFields = GenConstant(SYMBOL,NegativeInfinity); nextNode->constraints->maxFields = GenConstant(SYMBOL,PositiveInfinity); nextNode->derivedConstraints = TRUE; /*====================================================*/ /* If we're not dealing with a multifield constraint, */ /* then no further modifications are needed to the */ /* min and max constraints for this constraint. */ /*====================================================*/ if ((nextNode->type != MF_WILDCARD) && (nextNode->type != MF_VARIABLE)) { continue; } /*==========================================================*/ /* Create a separate constraint record to keep track of the */ /* cardinality information for this multifield constraint. */ /*==========================================================*/ tempConstraints = GetConstraintRecord(); SetConstraintType(MULTIFIELD,tempConstraints); tempConstraints->singlefieldsAllowed = FALSE; tempConstraints->multifield = nextNode->constraints; nextNode->constraints = tempConstraints; /*=====================================================*/ /* Adjust the min and max field values for this single */ /* multifield constraint based on the min and max */ /* fields for the entire slot and the number of single */ /* field values contained in the slot. */ /*=====================================================*/ if (theConstraints->maxFields->value != PositiveInfinity) { ReturnExpression(tempConstraints->maxFields); tempConstraints->maxFields = GenConstant(INTEGER,AddLong(ValueToLong(theConstraints->maxFields->value) - numberOfSingleFields)); } if ((numberOfMultifields == 1) && (theConstraints->minFields->value != NegativeInfinity)) { ReturnExpression(tempConstraints->minFields); tempConstraints->minFields = GenConstant(INTEGER,AddLong(ValueToLong(theConstraints->minFields->value) - numberOfSingleFields)); } } /*================================================*/ /* If a multifield slot is being parsed, place a */ /* node on top of the list of constraints parsed. */ /*================================================*/ if (multifieldSlot) { nextNode = GetLHSParseNode(); nextNode->type = MF_WILDCARD; nextNode->multifieldSlot = TRUE; nextNode->bottom = topNode; nextNode->slot = theSlot; nextNode->slotNumber = slotNumber; nextNode->index = startPosition; nextNode->constraints = theConstraints; topNode = nextNode; TallyFieldTypes(topNode->bottom); } /*=================================*/ /* Return the list of constraints. */ /*=================================*/ return(topNode); }
void EditPolyMod::OnParamSet(PB2Value& v, ParamID id, int tabIndex, TimeValue t) { switch( id ) { case epm_constrain_type: SetConstraintType(v.i); break; case epm_select_mode: SetSelectMode(v.i); break; case epm_ss_use: //When the soft selection is turned off, end any active paint session if( (!v.i) && InPaintMode() ) EndPaintMode(); break; case epm_ss_lock: { BOOL selActive = IsPaintDataActive(PAINTMODE_SEL); if( v.i && !selActive ) //Enable the selection lock; Activate the paintmesh selection ActivatePaintData(PAINTMODE_SEL); else if( (!v.i) && selActive ) { //Disable the selection lock; De-activate the paintmesh selection if( InPaintMode() ) EndPaintMode (); //end any active paint mode DeactivatePaintData(PAINTMODE_SEL); } //NOTE: SetEnables() is called by OnPaintDataActive() when activating or deactivating InvalidateDistanceCache (); if (mpDialogSoftsel) mpDialogSoftsel->RedrawViews (t); break; } case epm_paintsel_size: case epm_paintdeform_size: SetPaintBrushSize(v.f); UpdatePaintBrush(); break; case epm_paintsel_strength: case epm_paintdeform_strength: SetPaintBrushStrength(v.f); UpdatePaintBrush(); break; case epm_paintsel_value: case epm_paintdeform_value: case epm_paintdeform_axis: UpdatePaintBrush(); break; case epm_paintsel_mode: if( v.i!=GetPaintMode() ) { BOOL valid = FALSE; HWND hwnd = (mpDialogSoftsel==NULL? NULL : mpDialogSoftsel->GetHWnd()); if( v.i==PAINTMODE_PAINTSEL ) valid = IsButtonEnabled( hwnd, IDC_PAINTSEL_PAINT ); if( v.i==PAINTMODE_BLURSEL ) valid = IsButtonEnabled( hwnd, IDC_PAINTSEL_BLUR ); if( v.i==PAINTMODE_ERASESEL ) valid = IsButtonEnabled( hwnd, IDC_PAINTSEL_REVERT ); if( v.i==PAINTMODE_OFF ) valid = TRUE; if( valid ) OnPaintBtn(v.i, t); } break; case epm_paintdeform_mode: if( v.i!=GetPaintMode() ) { BOOL valid = FALSE; HWND hwnd = (mpDialogPaintDeform==NULL? NULL : mpDialogPaintDeform->GetHWnd()); if( v.i==PAINTMODE_PAINTPUSHPULL ) valid = IsButtonEnabled( hwnd, IDC_PAINTDEFORM_PUSHPULL ); if( v.i==PAINTMODE_PAINTRELAX ) valid = IsButtonEnabled( hwnd, IDC_PAINTDEFORM_RELAX ); if( v.i==PAINTMODE_ERASEDEFORM ) valid = IsButtonEnabled( hwnd, IDC_PAINTDEFORM_REVERT ); if( v.i==PAINTMODE_OFF ) valid = TRUE; if( valid ) OnPaintBtn(v.i, t); } break; } }
static intBool ParseTypeAttribute( void *theEnv, const char *readSource, CONSTRAINT_RECORD *constraints) { int typeParsed = FALSE; int variableParsed = FALSE; int theType; struct token inputToken; /*======================================*/ /* Continue parsing types until a right */ /* parenthesis is encountered. */ /*======================================*/ SavePPBuffer(theEnv," "); for (GetToken(theEnv,readSource,&inputToken); inputToken.type != RPAREN; GetToken(theEnv,readSource,&inputToken)) { SavePPBuffer(theEnv," "); /*==================================*/ /* If the token is a symbol then... */ /*==================================*/ if (inputToken.type == SYMBOL) { /*==============================================*/ /* ?VARIABLE can't be used with type constants. */ /*==============================================*/ if (variableParsed == TRUE) { SyntaxErrorMessage(theEnv,"type attribute"); return(FALSE); } /*========================================*/ /* Check for an appropriate type constant */ /* (e.g. SYMBOL, FLOAT, INTEGER, etc.). */ /*========================================*/ theType = GetConstraintTypeFromTypeName(ValueToString(inputToken.value)); if (theType < 0) { SyntaxErrorMessage(theEnv,"type attribute"); return(FALSE); } /*==================================================*/ /* Change the type restriction flags to reflect the */ /* type restriction. If the type restriction was */ /* already specified, then a error is generated. */ /*==================================================*/ if (SetConstraintType(theType,constraints)) { SyntaxErrorMessage(theEnv,"type attribute"); return(FALSE); } constraints->anyAllowed = FALSE; /*===========================================*/ /* Remember that a type constant was parsed. */ /*===========================================*/ typeParsed = TRUE; } /*==============================================*/ /* Otherwise if the token is a variable then... */ /*==============================================*/ else if (inputToken.type == SF_VARIABLE) { /*========================================*/ /* The only variable allowd is ?VARIABLE. */ /*========================================*/ if (strcmp(inputToken.printForm,"?VARIABLE") != 0) { SyntaxErrorMessage(theEnv,"type attribute"); return(FALSE); } /*===================================*/ /* ?VARIABLE can't be used more than */ /* once or with type constants. */ /*===================================*/ if (typeParsed || variableParsed) { SyntaxErrorMessage(theEnv,"type attribute"); return(FALSE); } /*======================================*/ /* Remember that a variable was parsed. */ /*======================================*/ variableParsed = TRUE; } /*====================================*/ /* Otherwise this is an invalid value */ /* for the type attribute. */ /*====================================*/ else { SyntaxErrorMessage(theEnv,"type attribute"); return(FALSE); } } /*=====================================*/ /* Fix up pretty print representation. */ /*=====================================*/ PPBackup(theEnv); PPBackup(theEnv); SavePPBuffer(theEnv,")"); /*=======================================*/ /* The type attribute must have a value. */ /*=======================================*/ if ((! typeParsed) && (! variableParsed)) { SyntaxErrorMessage(theEnv,"type attribute"); return(FALSE); } /*===========================================*/ /* Return TRUE indicating the type attibuted */ /* was successfully parsed. */ /*===========================================*/ return(TRUE); }
void Constraint::Clear() { SetConstraintType(CONSTRAINT_NONE); }
static BOOLEAN CheckArgumentForConstraintError( void *theEnv, struct expr *expressionList, struct expr *lastOne, int i, struct FunctionDefinition *theFunction, struct lhsParseNode *theLHS) { int theRestriction; CONSTRAINT_RECORD *constraint1, *constraint2, *constraint3, *constraint4; struct lhsParseNode *theVariable; struct expr *tmpPtr; int rv = FALSE; /*=============================================================*/ /* Skip anything that isn't a variable or isn't an argument to */ /* a user defined function (i.e. deffunctions and generic have */ /* no constraint information so they aren't checked). */ /*=============================================================*/ if ((expressionList->type != SF_VARIABLE) || (theFunction == NULL)) { return (rv); } /*===========================================*/ /* Get the restrictions for the argument and */ /* convert them to a constraint record. */ /*===========================================*/ theRestriction = GetNthRestriction(theFunction,i); constraint1 = ArgumentTypeToConstraintRecord(theEnv,theRestriction); /*================================================*/ /* Look for the constraint record associated with */ /* binding the variable in the LHS of the rule. */ /*================================================*/ theVariable = FindVariable((SYMBOL_HN *) expressionList->value,theLHS); if (theVariable != NULL) { if (theVariable->type == MF_VARIABLE) { constraint2 = GetConstraintRecord(theEnv); SetConstraintType(MULTIFIELD,constraint2); } else if (theVariable->constraints == NULL) { constraint2 = GetConstraintRecord(theEnv); } else { constraint2 = CopyConstraintRecord(theEnv,theVariable->constraints); } } else { constraint2 = NULL; } /*================================================*/ /* Look for the constraint record associated with */ /* binding the variable on the RHS of the rule. */ /*================================================*/ constraint3 = FindBindConstraints(theEnv,(SYMBOL_HN *) expressionList->value); /*====================================================*/ /* Union the LHS and RHS variable binding constraints */ /* (the variable must satisfy one or the other). */ /*====================================================*/ constraint3 = UnionConstraints(theEnv,constraint3,constraint2); /*====================================================*/ /* Intersect the LHS/RHS variable binding constraints */ /* with the function argument restriction constraints */ /* (the variable must satisfy both). */ /*====================================================*/ constraint4 = IntersectConstraints(theEnv,constraint3,constraint1); /*====================================*/ /* Check for unmatchable constraints. */ /*====================================*/ if (UnmatchableConstraint(constraint4) && EnvGetStaticConstraintChecking(theEnv)) { PrintErrorID(theEnv,"RULECSTR",3,TRUE); EnvPrintRouter(theEnv,WERROR,"Previous variable bindings of ?"); EnvPrintRouter(theEnv,WERROR,ValueToString((SYMBOL_HN *) expressionList->value)); EnvPrintRouter(theEnv,WERROR," caused the type restrictions"); EnvPrintRouter(theEnv,WERROR,"\nfor argument #"); PrintLongInteger(theEnv,WERROR,(long int) i); EnvPrintRouter(theEnv,WERROR," of the expression "); tmpPtr = lastOne->nextArg; lastOne->nextArg = NULL; PrintExpression(theEnv,WERROR,lastOne); lastOne->nextArg = tmpPtr; EnvPrintRouter(theEnv,WERROR,"\nfound in the rule's RHS to be violated.\n"); rv = TRUE; } /*===========================================*/ /* Free the temporarily created constraints. */ /*===========================================*/ RemoveConstraint(theEnv,constraint1); RemoveConstraint(theEnv,constraint2); RemoveConstraint(theEnv,constraint3); RemoveConstraint(theEnv,constraint4); /*========================================*/ /* Return TRUE if unmatchable constraints */ /* were detected, otherwise FALSE. */ /*========================================*/ return(rv); }