ExprIntrp系列
1.ExprIntrp
ExprIntrp
是 OpenCASCADE 的表达式解释器模块,负责将文本表达式解析为 OpenCASCADE 的符号表达式树。以下是该模块的详细源码解析:
1.1.模件
核心类概览
文件结构
ExprIntrp_Generator.hxx
:表达式生成器ExprIntrp_Parser.hxx
:解析器接口ExprIntrp_yacc.hxx
:语法分析器实现ExprIntrp_lex.pxx
:词法分析器实现ExprIntrp_Stack.hxx
:表达式栈ExprIntrp_Recept.hxx
:语法规则容器
1.2.核心类解析
1.2.1. ExprIntrp_Generator
(表达式生成器)
关键方法
class ExprIntrp_Generator : public Standard_Transient {
public:
// 创建生成器实例
Standard_EXPORT static Handle(ExprIntrp_Generator) Create();
// 处理表达式字符串
Standard_EXPORT void Process(const TCollection_AsciiString& str);
// 获取解析结果
Standard_EXPORT Handle(Expr_GeneralExpression) GetResult() const;
// 定义函数
Standard_EXPORT void DefineFunction(const TCollection_AsciiString& name, const Standard_Integer nargs);
// 定义变量
Standard_EXPORT void DefineVariable(const TCollection_AsciiString& name);
// 定义常量
Standard_EXPORT void DefineConstant(const TCollection_AsciiString& name, const Standard_Real value);
// 内部表达式栈操作
Standard_EXPORT void Push(const Handle(Expr_GeneralExpression)& exp);
Standard_EXPORT Handle(Expr_GeneralExpression) Pop();
};
工作流程
- 初始化:创建生成器实例
- 定义符号:注册变量、常量、函数
- 处理表达式:
Process()
调用词法/语法分析 - 获取结果:
GetResult()
返回表达式树
1.2.2. ExprIntrp_Parser
(解析器)
接口定义
class ExprIntrp_Parser {
public:
// 单例访问
Standard_EXPORT static ExprIntrp_Parser& Instance();
// 解析表达式
Standard_EXPORT void Parse(const TCollection_AsciiString& str);
// 获取当前生成器
Standard_EXPORT Handle(ExprIntrp_Generator) Generator() const;
// 设置生成器
Standard_EXPORT void SetGenerator(const Handle(ExprIntrp_Generator)& gen);
};
设计特点
- 单例模式:全局唯一解析器实例
- 插件式生成器:可替换不同生成器实现
- 线程不安全:需外部同步
1.2.3. ExprIntrp_Stack
(表达式栈)
核心实现
class ExprIntrp_Stack {
public:
// 压入表达式
void Push(const Handle(Expr_GeneralExpression)& exp);
// 弹出表达式
Handle(Expr_GeneralExpression) Pop();
// 栈顶元素
Handle(Expr_GeneralExpression) Top() const;
// 栈大小
Standard_Integer Size() const;
private:
NCollection_List<Handle(Expr_GeneralExpression)> myStack;
};
在解析中的作用
- 存储中间表达式结果
- 处理运算符优先级
- 管理括号嵌套层级
1.3.解析流程
词法分析 (ExprIntrp_lex
)
%{
#include "ExprIntrp_yacc.hxx"
%}
%option noyywrap
DIGIT [0-9]
INT {DIGIT}+
FLOAT {INT}("."{INT})?([eE][-+]?{INT})?
ID [a-zA-Z_][a-zA-Z0-9_]*
%%
{FLOAT} { yylval.real = atof(yytext); return TKN_NUMERIC; }
{ID} { yylval.string = new TCollection_AsciiString(yytext);
return TKN_IDENTIFIER; }
"+" { return TKN_PLUS; }
"-" { return TKN_MINUS; }
"*" { return TKN_MULTIPLY; }
"/" { return TKN_DIVIDE; }
"^" { return TKN_POWER; }
"(" { return TKN_LPAREN; }
")" { return TKN_RPAREN; }
语法分析 (ExprIntrp_yacc
)
%{
#include "ExprIntrp_Generator.hxx"
%}
%token TKN_NUMERIC TKN_IDENTIFIER
%token TKN_PLUS TKN_MINUS TKN_MULTIPLY TKN_DIVIDE TKN_POWER
%token TKN_LPAREN TKN_RPAREN
%left TKN_PLUS TKN_MINUS
%left TKN_MULTIPLY TKN_DIVIDE
%right TKN_POWER
%%
expression:
term
| expression TKN_PLUS term { $$ = new Expr_Sum($1, $3); }
| expression TKN_MINUS term { $$ = new Expr_Difference($1, $3); }
;
term:
factor
| term TKN_MULTIPLY factor { $$ = new Expr_Product($1, $3); }
| term TKN_DIVIDE factor { $$ = new Expr_Ratio($1, $3); }
;
factor:
primary
| primary TKN_POWER factor { $$ = new Expr_Exponential($1, $3); }
;
primary:
TKN_NUMERIC { $$ = new Expr_NumericValue($1); }
| TKN_IDENTIFIER { $$ = generator->GetNamed($1); }
| TKN_LPAREN expression TKN_RPAREN { $$ = $2; }
;
解析过程
- 词法分析:将输入字符串转换为 token 流
- 语法分析:根据文法规则构建表达式树
- 语义处理:处理符号引用和类型检查
- 结果生成:返回完整的表达式树
1.4.关键特性
1.4.1. 运算符优先级处理
优先级 | 运算符 | 结合性 |
---|---|---|
最高 | ^ (幂运算) |
右结合 |
* , / |
左结合 | |
最低 | + , - |
左结合 |
1.4.2. 内置函数支持
// 注册数学函数
generator->DefineFunction("sin", 1); // sin(x)
generator->DefineFunction("cos", 1); // cos(x)
generator->DefineFunction("sqrt", 1); // sqrt(x)
// 函数调用解析
function_call:
TKN_IDENTIFIER TKN_LPAREN arguments TKN_RPAREN {
$$ = generator->CreateFunction($1, $3);
}
;
1.4.3. 错误处理机制
// 语法错误回调
void ExprIntrp_Parser::Error(const char* msg) {
// 收集错误位置
Standard_Integer line, column;
GetLocation(line, column);
// 抛出异常
throw ExprIntrp_SyntaxError(line, column, msg);
}
// 异常类
class ExprIntrp_SyntaxError : public Standard_Failure {
public:
ExprIntrp_SyntaxError(Standard_Integer line, Standard_Integer col, const char* msg)
: Standard_Failure(msg), myLine(line), myColumn(col) {}
Standard_Integer Line() const { return myLine; }
Standard_Integer Column() const { return myColumn; }
private:
Standard_Integer myLine;
Standard_Integer myColumn;
};
1.5.使用示例
基本表达式解析
// 创建解析器
ExprIntrp_Parser& parser = ExprIntrp_Parser::Instance();
// 创建生成器
Handle(ExprIntrp_Generator) gen = ExprIntrp_Generator::Create();
parser.SetGenerator(gen);
// 定义变量
gen->DefineVariable("x");
gen->DefineVariable("y");
// 解析表达式
parser.Parse("x^2 + 2*x*y + y^2");
// 获取表达式树
Handle(Expr_GeneralExpression) expr = gen->GetResult();
自定义函数使用
// 自定义函数实现
class CustomFunc : public Expr_UnaryFunction {
public:
CustomFunc(const Handle(Expr_GeneralExpression)& arg)
: Expr_UnaryFunction("custom", arg) {}
Standard_Real Evaluate(...) const override {
Standard_Real x = Operand()->Evaluate(vars, vals);
return x * exp(-x);
}
};
// 注册自定义函数
gen->DefineFunction("custom", 1);
// 覆盖函数创建逻辑
gen->OverrideFunctionCreator("custom",
[](const ExprIntrp_SequenceOfExpression& args) {
if (args.Length() != 1) {
throw ExprIntrp_InvalidFunction("custom requires 1 argument");
}
return new CustomFunc(args.Value(1));
});
// 解析含自定义函数的表达式
parser.Parse("custom(sin(x))");
1.6.扩展机制
1.6.1. 自定义运算符
// 添加新运算符 "⊗" 表示张量积
gen->DefineInfixOperator("⊗",
[](const Handle(Expr_GeneralExpression)& left,
const Handle(Expr_GeneralExpression)& right) {
return new TensorProduct(left, right);
},
/*优先级*/ 3, /*结合性*/ left);
// 更新词法分析
%%
"⊗" { return TKN_TENSOR_PRODUCT; }
1.6.2. 语法规则扩展
// 添加矩阵语法支持
matrix:
TKN_LBRACKET matrix_rows TKN_RBRACKET
{ $$ = new Expr_Matrix($2); }
;
matrix_rows:
matrix_row
| matrix_rows TKN_SEMICOLON matrix_row
{ $$ = $1.Concatenate($3); }
;
1.6.3. 上下文感知解析
// 根据上下文切换解析模式
void ExprIntrp_Parser::SetContext(ParsingContext ctx) {
switch(ctx) {
case GeometricConstraints:
LoadGrammar("geom_constraints.yacc");
break;
case PhysicalEquations:
LoadGrammar("physics_equations.yacc");
break;
}
}
1.7.性能优化
1.7.1. 表达式缓存
class ExprIntrp_Generator {
private:
NCollection_DataMap<TCollection_AsciiString, Handle(Expr_GeneralExpression)> myExpressionCache;
public:
Handle(Expr_GeneralExpression) ParseCached(const TCollection_AsciiString& expr) {
if (myExpressionCache.IsBound(expr)) {
return myExpressionCache(expr)->Copy();
}
Process(expr);
Handle(Expr_GeneralExpression) result = GetResult();
myExpressionCache.Bind(expr, result->Copy());
return result;
}
};
1.7.2. 增量解析
// 支持增量输入
void ExprIntrp_Parser::AppendInput(const TCollection_AsciiString& partial) {
myLexer->AppendInput(partial);
if (myLexer->HasCompleteToken()) {
yyparse();
}
}
1.7.3. 并行解析
// 线程安全的解析器池
class ExprIntrp_ParserPool {
public:
Handle(ExprIntrp_Parser) AcquireParser() {
std::lock_guard<std::mutex> lock(myMutex);
if (myAvailable.empty()) {
return new ExprIntrp_Parser();
}
auto parser = myAvailable.back();
myAvailable.pop_back();
return parser;
}
void ReleaseParser(Handle(ExprIntrp_Parser)& parser) {
std::lock_guard<std::mutex> lock(myMutex);
parser->Reset();
myAvailable.push_back(parser);
}
private:
std::vector<Handle(ExprIntrp_Parser)> myAvailable;
std::mutex myMutex;
};
1.8.典型应用场景
CAD 参数化建模
# 在 OpenCASCADE 的 Python 绑定中
import OCC.ExprIntrp
# 创建参数化圆柱体
radius_expr = OCC.ExprIntrp.Parse("base_radius + t * growth_rate")
height_expr = OCC.ExprIntrp.Parse("initial_height * exp(-decay_factor * t)")
for t in [0, 0.5, 1.0]:
cylinder = make_cylinder(
radius=radius_expr.Evaluate(t=t),
height=height_expr.Evaluate(t=t)
)
工程约束求解
// 创建约束系统
Handle(Expr_SystemRelation) system = new Expr_SystemRelation();
// 添加约束:x^2 + y^2 = r^2
parser.Parse("x^2 + y^2 - r^2 = 0");
system->Add(parser.Generator()->GetResult()->AsRelation());
// 添加约束:x + y = 10
parser.Parse("x + y - 10 = 0");
system->Add(parser.Generator()->GetResult()->AsRelation());
// 求解约束
Handle(Expr_Solver) solver = new Expr_Solver(system);
solver->Solve();
物理仿真方程
// 解析热传导方程
parser.Parse("k * (d^2T/dx^2 + d^2T/dy^2) + Q = rho * Cp * dT/dt");
// 获取偏微分方程表达式
Handle(Expr_PDE) heatEquation = parser.Generator()->GetResult()->AsPDE();
// 设置边界条件
heatEquation->SetBoundaryCondition("x=0", "T=300");
heatEquation->SetBoundaryCondition("x=L", "dT/dx=0");
// 数值求解
Handle(FEM_Solver) femSolver = new FEM_Solver(heatEquation);
femSolver->Solve();
1.9.模块局限性
1.9.1. 语法限制
- 不支持自定义运算符优先级
- 缺乏完整的类型系统
- 函数重载支持有限
1.9.2. 性能瓶颈
- 递归下降解析器对长表达式效率低
- 缺乏 JIT 编译优化
- 无表达式预编译机制
1.9.3. 扩展复杂性
- 修改语法需重新生成解析器
- 自定义函数集成不够直观
- 错误消息不够友好
1.10.总结
ExprIntrp
模块是 OpenCASCADE 的表达式解析核心引擎,其设计特点包括:
- 分层架构:
- 词法分析 (
lex
) - 语法分析 (
yacc
) - 语义处理 (
Generator
) - 表达式构建 (
Stack
)
- 词法分析 (
- 关键能力:
- 文本到表达式树的转换
- 运算符优先级处理
- 自定义函数集成
- 错误定位与报告
- 应用价值:
- CAD 参数化设计
- 工程约束求解
- 物理方程建模
- 优化问题定义
- 扩展机制:
- 自定义运算符
- 语法规则扩展
- 上下文感知解析
- 多领域方言支持
- 优化方向:
- 表达式缓存
- 增量解析
- 并行处理
- JIT 编译优化
ExprIntrp
作为 OpenCASCADE 数学框架的关键组成部分,桥接了文本表达与符号计算之间的鸿沟,为复杂工程系统的建模与分析提供了强大的基础支持。
2.ExprIntrp_Analysis
ExprIntrp_Analysis
是 OpenCASCADE 表达式解释器模块的核心状态管理类,负责维护解析过程中的上下文和符号表。以下是对其源码的详细解析:
2.1.类定义与职责
头文件位置
ExprIntrp_Analysis.hxx
类声明
class ExprIntrp_Analysis : public Standard_Transient {
DEFINE_STANDARD_RTTIEXT(ExprIntrp_Analysis, Standard_Transient)
public:
// 构造函数
Standard_EXPORT ExprIntrp_Analysis();
// 栈操作
Standard_EXPORT void Push(const Handle(Expr_GeneralExpression)& exp);
Standard_EXPORT Handle(Expr_GeneralExpression) Pop();
Standard_EXPORT Handle(Expr_GeneralExpression) Top() const;
// 结果管理
Standard_EXPORT void SetResult(const Handle(Expr_GeneralExpression)& exp);
Standard_EXPORT const Handle(Expr_GeneralExpression)& Result() const;
Standard_EXPORT void SetRelation(const Handle(Expr_GeneralRelation)& rel);
Standard_EXPORT const Handle(Expr_GeneralRelation)& Relation() const;
// 符号表管理
Standard_EXPORT void DefineFunction(const TCollection_AsciiString& name);
Standard_EXPORT void DefineVariable(const TCollection_AsciiString& name);
Standard_EXPORT void DefineConstant(const TCollection_AsciiString& name, Standard_Real value);
// 符号查询
Standard_EXPORT Standard_Boolean IsFunction(const TCollection_AsciiString& name) const;
Standard_EXPORT Standard_Boolean IsVariable(const TCollection_AsciiString& name) const;
Standard_EXPORT Standard_Boolean IsConstant(const TCollection_AsciiString& name) const;
Standard_EXPORT Standard_Real GetConstant(const TCollection_AsciiString& name) const;
// 状态重置
Standard_EXPORT void Reset();
private:
ExprIntrp_Stack myStack; // 表达式栈
Handle(Expr_GeneralExpression) myResultExp; // 表达式结果
Handle(Expr_GeneralRelation) myResultRel; // 关系结果
// 符号表
NCollection_DataMap<TCollection_AsciiString, Standard_Integer> myFunctions;
NCollection_DataMap<TCollection_AsciiString, Handle(Expr_NamedUnknown)> myVariables;
NCollection_DataMap<TCollection_AsciiString, Standard_Real> myConstants;
};
2.2.核心组件解析
2.2.1. 表达式栈 (ExprIntrp_Stack
)
class ExprIntrp_Stack {
public:
void Push(const Handle(Expr_GeneralExpression)& exp);
Handle(Expr_GeneralExpression) Pop();
Standard_Boolean IsEmpty() const;
private:
NCollection_List<Handle(Expr_GeneralExpression)> myStack;
};
- LIFO结构:后进先出的栈结构
- 中间结果存储:保存解析过程中的部分表达式
- 运算符处理:协助处理运算符优先级和结合性
2.2.2. 符号表系统
函数表 (myFunctions
)
NCollection_DataMap<TCollection_AsciiString, Standard_Integer> myFunctions;
- 键:函数名称(如 “sin”、“customFunc”)
- 值:参数数量(如 sin→1,max→2)
- 注册方式:
DefineFunction("sin", 1)
变量表 (myVariables
)
NCollection_DataMap<TCollection_AsciiString, Handle(Expr_NamedUnknown)> myVariables;
- 键:变量名称(如 “x”、“radius”)
- 值:对应的
Expr_NamedUnknown
实例 - 特点:相同名称的变量返回相同实例(单例行为)
常量表 (myConstants
)
NCollection_DataMap<TCollection_AsciiString, Standard_Real> myConstants;
- 键:常量名称(如 “PI”、“E”)
- 值:数值(如 PI→3.14159)
- 预定义常量:通常包含数学常数
2.2.3. 结果管理
// 设置表达式结果
void SetResult(const Handle(Expr_GeneralExpression)& exp);
// 设置关系结果
void SetRelation(const Handle(Expr_GeneralRelation)& rel);
// 获取结果
const Handle(Expr_GeneralExpression)& Result() const;
const Handle(Expr_GeneralRelation)& Relation() const;
- 双结果系统:支持表达式和关系两种解析结果
- 互斥存储:一次解析只能设置一种结果类型
- 使用场景:
- 表达式:
2*x + 3
- 关系:
x^2 + y^2 = r^2
- 表达式:
2.3.工作流程
解析过程中的交互
典型解析步骤
- 初始化:创建
ExprIntrp_Analysis
实例 - 注册符号:定义变量、函数、常量
- 开始解析:
Generator
使用分析实例 - 栈操作:解析过程中推入/弹出中间表达式
- 结果设置:解析完成时设置最终结果
- 获取结果:从分析实例提取解析结果
2.4.关键方法实现
2.4.1. 符号定义
void DefineVariable(const TCollection_AsciiString& name) {
if (myVariables.IsBound(name)) {
ExprIntrp::RaiseVariableAlreadyDefined(name);
}
myVariables.Bind(name, new Expr_NamedUnknown(name));
}
void DefineConstant(const TCollection_AsciiString& name, Standard_Real value) {
if (myConstants.IsBound(name)) {
ExprIntrp::RaiseConstantAlreadyDefined(name);
}
myConstants.Bind(name, value);
}
2.4.2. 符号查询
Standard_Boolean IsVariable(const TCollection_AsciiString& name) const {
return myVariables.IsBound(name) || myConstants.IsBound(name);
}
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) const {
if (myVariables.IsBound(name)) {
return myVariables(name);
}
if (myConstants.IsBound(name)) {
return new Expr_NumericValue(myConstants(name));
}
ExprIntrp::RaiseUndefinedVariable(name);
return nullptr; // never reached
}
2.4.3. 栈操作
void Push(const Handle(Expr_GeneralExpression)& exp) {
if (exp.IsNull()) {
Standard_NullObject::Raise("ExprIntrp_Analysis::Push");
}
myStack.Push(exp);
}
Handle(Expr_GeneralExpression) Pop() {
if (myStack.IsEmpty()) {
ExprIntrp::RaiseStackIsEmpty();
}
return myStack.Pop();
}
2.5.设计特点
2.5.1. 状态集中管理
- 统一存储:所有解析状态(栈、符号表、结果)集中管理
- 隔离解析器:使解析器实现无状态,易于复用
- 上下文保存:支持多解析上下文切换
2.5.2. 符号表高效查找
- 哈希映射:使用
NCollection_DataMap
实现 O(1) 复杂度查找 - 名称规范化:存储前统一转换为小写(可选)
- 作用域管理:单作用域设计(无嵌套作用域)
2.5.3. 错误处理机制
// 错误代码定义
enum ExprIntrp_ErrorCode {
UndefinedVariable,
FunctionNotDefined,
StackUnderflow,
// ...
};
// 统一错误处理
void ExprIntrp::RaiseError(ExprIntrp_ErrorCode code, const TCollection_AsciiString& info = "") {
switch(code) {
case UndefinedVariable:
throw ExprIntrp_UndefinedVariable(info);
case FunctionNotDefined:
throw ExprIntrp_FunctionNotDefined(info);
// ...
}
}
2.5.4. 线程安全考虑
- 非线程安全:设计为单线程使用
- 多实例支持:每个线程可创建独立分析实例
- 共享符号表:可通过复制构造函数共享预定义符号
2.6.使用模式
基本用法
// 创建分析上下文
Handle(ExprIntrp_Analysis) analysis = new ExprIntrp_Analysis();
// 注册符号
analysis->DefineVariable("x");
analysis->DefineConstant("PI", 3.1415926535);
analysis->DefineFunction("sin", 1);
// 创建生成器并关联分析上下文
Handle(ExprIntrp_Generator) gen = ExprIntrp_Generator::Create();
gen->SetAnalysis(analysis);
// 解析表达式
gen->Process("sin(PI * x)");
// 获取结果
Handle(Expr_GeneralExpression) expr = analysis->Result();
高级用法:多上下文管理
// 创建全局上下文(共享符号)
Handle(ExprIntrp_Analysis) globalCtx = new ExprIntrp_Analysis();
globalCtx->DefineConstant("E", 2.71828);
globalCtx->DefineFunction("log", 1);
// 创建专用上下文(继承全局符号)
Handle(ExprIntrp_Analysis) localCtx = new ExprIntrp_Analysis(*globalCtx);
localCtx->DefineVariable("t");
// 解析专用表达式
gen->SetAnalysis(localCtx);
gen->Process("log(E) * t");
2.7.扩展机制
2.7.1. 自定义符号处理器
class CustomSymbolHandler : public Standard_Transient {
public:
virtual Handle(Expr_GeneralExpression) HandleSymbol(const TCollection_AsciiString& name, ExprIntrp_Analysis& analysis) = 0;
};
// 在分析类中扩展
void ExprIntrp_Analysis::SetSymbolHandler(const Handle(CustomSymbolHandler)& handler) {
mySymbolHandler = handler;
}
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) const {
// 优先使用自定义处理器
if (!mySymbolHandler.IsNull()) {
auto result = mySymbolHandler->HandleSymbol(name, *this);
if (!result.IsNull()) return result;
}
// 默认处理...
}
2.7.2. 动态作用域
// 进入新作用域
void PushScope() {
myScopeStack.Push(myCurrentScope);
myCurrentScope = new SymbolScope();
}
// 退出作用域
void PopScope() {
if (myScopeStack.IsEmpty()) return;
myCurrentScope = myScopeStack.Pop();
}
// 作用域感知的符号查询
Standard_Boolean IsVariable(const TCollection_AsciiString& name) const {
return myCurrentScope->Variables().IsBound(name) || myGlobalScope->Variables().IsBound(name);
}
2.7.3. 符号类型推断
// 自动识别未定义符号
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) const {
if (myVariables.IsBound(name)) {
return myVariables(name);
}
// 尝试识别为函数(零参数)
if (myAutoDetectFunctions && !myFunctions.IsBound(name)) {
DefineFunction(name, 0); // 注册为零参数函数
return new ExprIntrp_FunctionCall(name, ExprIntrp_SequenceOfExpression());
}
// 尝试识别为变量
DefineVariable(name);
return myVariables(name);
}
2.8.性能优化
2.8.1. 符号表缓存
// 缓存最近访问的符号
mutable NCollection_LRU<TCollection_AsciiString, Handle(Expr_GeneralExpression)> mySymbolCache;
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) const {
// 先检查缓存
if (mySymbolCache.Contains(name)) {
return mySymbolCache.Find(name);
}
// 正常查找...
Handle(Expr_GeneralExpression) result = ...;
// 更新缓存
mySymbolCache.Bind(name, result);
return result;
}
2.8.2. 延迟符号解析
// 特殊代理表达式
class LazySymbol : public Expr_GeneralExpression {
public:
LazySymbol(const TCollection_AsciiString& name, const ExprIntrp_Analysis& analysis) : myName(name), myAnalysis(analysis) {}
Standard_Real Evaluate(...) const override {
return Resolve()->Evaluate(vars, vals);
}
private:
Handle(Expr_GeneralExpression) Resolve() const {
if (myResolved.IsNull()) {
myResolved = myAnalysis.GetNamed(myName);
}
return myResolved;
}
TCollection_AsciiString myName;
mutable Handle(Expr_GeneralExpression) myResolved;
const ExprIntrp_Analysis& myAnalysis;
};
// 在GetNamed中返回代理
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) const {
return new LazySymbol(name, *this);
}
2.8.3. 批量符号注册
// 从配置文件加载符号
void LoadSymbolsFromConfig(const TCollection_AsciiString& configFile) {
// 解析配置文件
NCollection_DataMap<TCollection_AsciiString, Standard_Real> constants;
NCollection_List<TCollection_AsciiString> variables;
// ...
// 批量注册
myConstants.Unite(constants);
for (auto& var : variables) {
DefineVariable(var);
}
}
2.9.典型应用场景
CAD 参数化设计
// 创建设计参数上下文
Handle(ExprIntrp_Analysis) designCtx = new ExprIntrp_Analysis();
designCtx->DefineVariable("length");
designCtx->DefineVariable("width");
designCtx->DefineConstant("thickness", 5.0);
// 解析设计规则
parser.Parse("volume = length * width * thickness");
// 在交互环境中更新
designCtx->SetVariableValue("length", 100.0);
designCtx->SetVariableValue("width", 50.0);
Standard_Real vol = designCtx->Evaluate("volume");
工程计算模板
// 创建计算模板
Handle(ExprIntrp_Analysis) template = new ExprIntrp_Analysis();
template->DefineFunction("stress", 3); // stress(F, A, matFactor)
template->Parse("s = stress(force, area, material_factor)");
// 客户端使用
template->SetVariableValue("force", 5000); // N
template->SetVariableValue("area", 0.01); // m²
template->SetVariableValue("material_factor", 1.5);
Standard_Real stress = template->Evaluate("s");
教学演示系统
// 创建交互式数学环境
Handle(ExprIntrp_Analysis) mathEnv = new ExprIntrp_Analysis();
mathEnv->DefineConstant("PI", 3.1415926535);
mathEnv->DefineFunction("deriv", 2); // deriv(expr, var)
// 用户输入
mathEnv->Process("f = x^2 + sin(y)");
mathEnv->Process("df_dx = deriv(f, x)");
// 求值演示
mathEnv->SetVariableValue("x", 2.0);
mathEnv->SetVariableValue("y", M_PI/2);
Standard_Real result = mathEnv->Evaluate("df_dx"); // 应为4.0
2.10.模块局限性
2.10.1. 作用域限制
- 单层作用域,不支持嵌套作用域
- 无法处理块级变量声明
2.10.2. 类型系统缺失
- 无数据类型区分(整数、浮点、布尔)
- 无类型检查机制
2.10.3. 符号冲突
- 变量、函数、常量共享命名空间
- 无法定义同名的变量和函数
2.10.4. 错误恢复
- 错误发生后无法恢复解析状态
- 缺乏详细的错误位置信息
2.11.总结
ExprIntrp_Analysis
是 OpenCASCADE 表达式解释器的状态管理核心:
核心职责:
- 维护表达式解析栈
- 管理符号表(变量、函数、常量)
- 存储解析结果(表达式/关系)
关键特性:
- 高效的符号查找(哈希映射)
- 双结果存储系统
- 可扩展的符号处理机制
- 错误处理框架
设计亮点:
- 集中式状态管理
- 轻量级栈实现
- 符号单例保证
- 上下文隔离支持
应用价值:
- CAD参数化设计
- 工程计算模板
- 交互式数学环境
- 约束规则管理
改进方向:
作为表达式解释器的基础设施,
ExprIntrp_Analysis
为 OpenCASCADE 的符号处理能力提供了关键支撑,使文本表达式到符号表达式的转换成为可能,在参数化设计和工程计算领域发挥着重要作用。3.ExprIntrp_Generator
ExprIntrp_Generator
是 OpenCASCADE 表达式解释器模块的核心类,负责将词法分析器和语法分析器的输出转换为表达式树。以下是对其源码的深入解析:3.1.类定义与继承关系
头文件位置
ExprIntrp_Generator.hxx
类声明
class ExprIntrp_Generator : public Standard_Transient { DEFINE_STANDARD_RTTIEXT(ExprIntrp_Generator, Standard_Transient) public: // 创建生成器实例(工厂方法) Standard_EXPORT static Handle(ExprIntrp_Generator) Create(); // 设置关联的分析上下文 Standard_EXPORT void SetAnalysis(const Handle(ExprIntrp_Analysis)& theAnalysis); // 处理表达式字符串 Standard_EXPORT void Process(const TCollection_AsciiString& str); // 获取解析结果 Standard_EXPORT Handle(Expr_GeneralExpression) GetResult() const; Standard_EXPORT Handle(Expr_GeneralRelation) GetRelation() const; // 符号定义接口 Standard_EXPORT void DefineFunction(const TCollection_AsciiString& name, Standard_Integer nbargs); Standard_EXPORT void DefineVariable(const TCollection_AsciiString& name); Standard_EXPORT void DefineConstant(const TCollection_AsciiString& name, Standard_Real value); // 栈操作 Standard_EXPORT void Push(const Handle(Expr_GeneralExpression)& exp); Standard_EXPORT Handle(Expr_GeneralExpression) Pop(); // 语法分析器接口 Standard_EXPORT virtual void Use(const Handle(ExprIntrp_yacc)& theParser); protected: // 构造函数 Standard_EXPORT ExprIntrp_Generator(); // 结果管理 Standard_EXPORT void SetResult(const Handle(Expr_GeneralExpression)& exp); Standard_EXPORT void SetRelation(const Handle(Expr_GeneralRelation)& rel); private: Handle(ExprIntrp_Analysis) myAnalysis; // 关联的分析上下文 Handle(ExprIntrp_yacc) myParser; // 语法分析器实例 };
3.2.核心组件解析
3.2.1. 与分析上下文的关联 (
ExprIntrp_Analysis
)void SetAnalysis(const Handle(ExprIntrp_Analysis)& theAnalysis) { myAnalysis = theAnalysis; }
- 职责代理:将符号定义和栈操作委托给分析上下文
- 状态共享:允许多个生成器共享同一上下文
- 生命周期:不持有所有权,需外部管理
3.2.2. 语法分析器集成 (
ExprIntrp_yacc
)virtual void Use(const Handle(ExprIntrp_yacc)& theParser) { myParser = theParser; myParser->SetGenerator(this); // 建立双向链接 }
- 插件式架构:支持不同的语法分析器实现
- 回调机制:语法分析器通过生成器构建表达式
- 默认实现:使用Bison生成的
ExprIntrp_yacc
3.3.关键方法实现
3.3.1. 表达式处理流程 (
Process
)void ExprIntrp_Generator::Process(const TCollection_AsciiString& str) { // 重置分析状态 myAnalysis->Reset(); // 配置词法分析器 ExprIntrp_lexer lexer; lexer.SetInput(str); // 配置语法分析器 myParser->SetScanner(&lexer); try { // 执行语法分析 myParser->parse(); // 检查结果有效性 if (myAnalysis->Result().IsNull() && myAnalysis->Relation().IsNull()) { ExprIntrp::RaiseNoResult(); } } catch (Standard_Failure) { // 异常处理 myAnalysis->Reset(); throw; } }
3.3.2. 符号定义实现
void DefineFunction(const TCollection_AsciiString& name, Standard_Integer nbargs) { if (myAnalysis.IsNull()) { Standard_NullObject::Raise("No analysis context set"); } myAnalysis->DefineFunction(name, nbargs); } void DefineVariable(const TCollection_AsciiString& name) { myAnalysis->DefineVariable(name); }
3.3.3. 栈操作实现
void Push(const Handle(Expr_GeneralExpression)& exp) { myAnalysis->Push(exp); } Handle(Expr_GeneralExpression) Pop() { return myAnalysis->Pop(); }
3.3.4. 结果获取方法
Handle(Expr_GeneralExpression) GetResult() const { return myAnalysis->Result(); } Handle(Expr_GeneralRelation) GetRelation() const { return myAnalysis->Relation(); }
3.4.表达式构建机制
3.4.1. 基础表达式构建
数值常量
// 在语法分析器中 case TKN_NUMERIC: generator->Push(new Expr_NumericValue(yylval.real)); break;
变量引用
case TKN_IDENTIFIER: generator->Push(generator->GetNamed(yylval.string)); break;
3.4.2. 二元运算处理
加法运算
// 在语法规则中 expression: expression '+' term { Handle(Expr_GeneralExpression) right = generator->Pop(); Handle(Expr_GeneralExpression) left = generator->Pop(); generator->Push(new Expr_Sum(left, right)); }
乘法运算
term: term '*' factor { Handle(Expr_GeneralExpression) right = generator->Pop(); Handle(Expr_GeneralExpression) left = generator->Pop(); generator->Push(new Expr_Product(left, right)); }
3.4.3. 函数调用处理
function_call: TKN_IDENTIFIER '(' arguments ')' { // 获取参数 ExprIntrp_SequenceOfExpression args = generator->PopArguments(); // 创建函数调用 generator->Push(new ExprIntrp_FunctionCall($1, args)); } arguments: /* 空 */ | expression_list ; expression_list: expression | expression_list ',' expression ;
3.5.高级功能实现
3.5.1. 关系表达式处理
relation: expression '=' expression { Handle(Expr_GeneralExpression) right = generator->Pop(); Handle(Expr_GeneralExpression) left = generator->Pop(); generator->SetRelation(new Expr_SingleRelation(left, right)); }
3.5.2. 自定义函数处理
// 函数创建接口 virtual Handle(Expr_GeneralFunction) CreateFunction(const TCollection_AsciiString& name, const ExprIntrp_SequenceOfExpression& args) { // 检查参数数量 Standard_Integer nbArgs = myAnalysis->FunctionArgs(name); if (args.Length() != nbArgs) { ExprIntrp::RaiseWrongArgs(name, nbArgs, args.Length()); } // 创建标准函数 if (name == "sin") { return new Expr_Sin(args.Value(1)); } // ... 其他内置函数 // 创建通用函数调用 return new ExprIntrp_FunctionCall(name, args); }
3.5.3. 运算符重载扩展
// 添加自定义运算符支持 void DefineOperator(const TCollection_AsciiString& op, Standard_Integer priority, OperatorAssociativity associativity, OperatorHandler handler) { myOperatorMap.Bind(op, OperatorInfo(priority, associativity, handler)); } // 在语法分析中使用 operator_expression: primary | operator_expression op_token operator_expression { OperatorInfo info = generator->GetOperatorInfo($2); Handle(Expr_GeneralExpression) right = generator->Pop(); Handle(Expr_GeneralExpression) left = generator->Pop(); generator->Push(info.Handler(left, right)); }
3.6.语法树优化
3.6.1. 常量折叠优化
// 在表达式构建时优化 void Push(const Handle(Expr_GeneralExpression)& exp) { // 尝试简化表达式 Handle(Expr_GeneralExpression) simplified = exp->ShallowSimplified(); // 如果是常量,直接存储数值 if (simplified->IsConstant()) { simplified = new Expr_NumericValue(simplified->Evaluate(NullVars, NullVals)); } myAnalysis->Push(simplified); }
3.6.2. 公共子表达式消除
// 公共子表达式缓存 NCollection_DataMap<Expr_GeneralExpression, Handle(Expr_GeneralExpression)> myExpressionCache; Handle(Expr_GeneralExpression) CreateExpression(ExprType type, ...) { // 构造临时表达式 Handle(Expr_GeneralExpression) temp = ...; // 检查是否已存在 if (myExpressionCache.IsBound(temp)) { return myExpressionCache.Find(temp); } // 简化并缓存 Handle(Expr_GeneralExpression) result = temp->ShallowSimplified(); myExpressionCache.Bind(result, result); return result; }
3.6.3. 死代码消除
// 在关系处理中优化 void SetRelation(const Handle(Expr_GeneralRelation)& rel) { // 移除恒真/恒假关系 if (rel->IsSatisfied() == Standard_True) { rel = new Expr_AlwaysTrue(); } else if (rel->IsSatisfied() == Standard_False) { rel = new Expr_AlwaysFalse(); } myAnalysis->SetRelation(rel); }
3.7.错误处理机制
3.7.1. 语法错误处理
// 在语法分析器中 void yyerror(const char* msg) { // 获取位置信息 Standard_Integer line = yylineno; Standard_Integer column = yycolumn; // 构建详细错误信息 TCollection_AsciiString fullMsg = "Line "; fullMsg += TCollection_AsciiString(line); fullMsg += ", column "; fullMsg += TCollection_AsciiString(column); fullMsg += ": "; fullMsg += msg; // 抛出异常 throw ExprIntrp_SyntaxError(fullMsg); }
3.7.2. 语义错误处理
未定义符号
Handle(Expr_GeneralExpression) GetNamed(const TCollection_AsciiString& name) { if (!myAnalysis->IsDefined(name)) { ExprIntrp::RaiseUndefinedSymbol(name); } return myAnalysis->GetNamed(name); }
参数不匹配
void CheckFunctionArgs(const TCollection_AsciiString& name, Standard_Integer expected, Standard_Integer actual) { if (expected != actual) { TCollection_AsciiString msg = "Function '"; msg += name; msg += "' expects "; msg += TCollection_AsciiString(expected); msg += " arguments, got "; msg += TCollection_AsciiString(actual); throw ExprIntrp_InvalidArgs(msg); } }
3.8.扩展机制
3.8.1. 自定义语法分析器
class CustomParser : public ExprIntrp_yacc { public: CustomParser(ExprIntrp_Generator* gen) : ExprIntrp_yacc(gen) {} protected: // 覆盖语法规则 virtual int parse() override { // 自定义解析逻辑 ... } }; // 在生成器中使用 generator->Use(new CustomParser(generator));
3.8.2. 表达式监听器
class ExprListener : public Standard_Transient { public: virtual void OnCreateExpression(const Handle(Expr_GeneralExpression)& exp) = 0; virtual void OnCreateRelation(const Handle(Expr_GeneralRelation)& rel) = 0; }; // 在生成器中添加 void AddListener(const Handle(ExprListener)& listener) { myListeners.Append(listener); } // 在创建表达式时通知 void SetResult(const Handle(Expr_GeneralExpression)& exp) { for (auto& listener : myListeners) { listener->OnCreateExpression(exp); } myAnalysis->SetResult(exp); }
3.8.3. 多方言支持
// 方言枚举 enum ExpressionDialect { StandardMath, // 默认数学表达式 GeometricConstraints, // 几何约束表达式 PhysicalUnits // 带单位的物理表达式 }; // 设置方言 void SetDialect(ExpressionDialect dialect) { switch (dialect) { case GeometricConstraints: myParser = new GeomConstraintParser(this); break; case PhysicalUnits: myParser = new PhysicalUnitParser(this); break; default: myParser = new ExprIntrp_yacc(this); } }
3.9.典型工作流程
基本表达式解析
关系表达式解析
3.10.性能优化策略
3.10.1. 表达式池技术
class ExpressionPool { public: Handle<Expr_GeneralExpression> GetOrCreate(ExprType type, ...) { // 创建临时键 ExpressionKey key(type, ...); // 检查池中是否存在 if (myPool.Find(key, expr)) { return expr; } // 创建新表达式 expr = new ...; myPool.Bind(key, expr); return expr; } private: NCollection_DataMap<ExpressionKey, Handle<Expr_GeneralExpression>> myPool; }; // 在生成器中使用 Handle<Expr_GeneralExpression> CreateSum(left, right) { return myPool->GetOrCreate(Expr_Sum, left, right); }
3.10.2. 增量解析
void AppendInput(const TCollection_AsciiString& partial) { // 追加到词法分析器 myLexer->AppendInput(partial); // 继续解析 if (myParser->CanResume()) { myParser->Resume(); } }
3.10.3. 预编译表达式
Handle<Expr_CompiledExpression> Compile(const TCollection_AsciiString& expr) { // 解析表达式 Process(expr); Handle<Expr_GeneralExpression> tree = GetResult(); // 转换为可执行形式 return new Expr_CompiledExpression(tree); }
3.11.应用场景
CAD 参数驱动设计
// 创建参数生成器 Handle(ExprIntrp_Generator) gen = ExprIntrp_Generator::Create(); Handle(ExprIntrp_Analysis) analysis = new ExprIntrp_Analysis(); gen->SetAnalysis(analysis); // 定义设计参数 gen->DefineVariable("length"); gen->DefineVariable("width"); gen->DefineConstant("thickness", 5.0); // 解析体积公式 gen->Process("volume = length * width * thickness"); // 更新参数值 analysis->SetValue("length", 100.0); analysis->SetValue("width", 50.0); // 计算体积 Standard_Real vol = analysis->Evaluate("volume"); // 100*50*5=25000
工程约束求解
// 创建约束系统 Handle(Expr_SystemRelation) system = new Expr_SystemRelation(); // 添加距离约束 gen->Process("(x2-x1)^2 + (y2-y1)^2 = dist^2"); system->Add(gen->GetRelation()); // 添加角度约束 gen->Process("atan2(y2-y1, x2-x1) = angle"); system->Add(gen->GetRelation()); // 求解系统 Handle(Expr_Solver) solver = new Expr_Solver(system); solver->SetVariable("x1", 0.0); solver->SetVariable("y1", 0.0); solver->SetVariable("dist", 10.0); solver->SetVariable("angle", M_PI/4); solver->Solve(); // 获取结果 Standard_Real x2 = solver->GetValue("x2"); // ~7.07 Standard_Real y2 = solver->GetValue("y2"); // ~7.07
动态公式计算
// 创建可重用的公式模板 Handle(Expr_CompiledExpression) formula = gen->Compile("k*x^2 + b"); // 高效计算多个x值 for (Standard_Real x = 0; x <= 10; x += 0.1) { formula->SetVariable("x", x); Standard_Real y = formula->Evaluate(); // 使用计算结果... }
3.12.总结
ExprIntrp_Generator
是 OpenCASCADE 表达式系统的转换引擎核心:- 核心职责:
- 协调词法分析、语法分析和语义分析
- 构建表达式树和关系对象
- 管理解析过程中的状态
- 关键特性:
- 模块化设计(可插拔分析器)
- 语法树优化(常量折叠、CSE)
- 丰富的错误处理机制
- 多方言支持
- 设计亮点:
- 性能优化:
- 表达式池减少对象创建
- 增量解析支持流式输入
- 预编译加速重复计算
- 应用价值:
- 参数化CAD建模
- 工程约束求解
- 动态公式计算
- 物理仿真建模
- 扩展能力:
- 自定义语法分析器
- 表达式监听器
- 多方言支持
- 运算符重载
ExprIntrp_Generator
作为 OpenCASCADE 表达式处理的枢纽,将文本表达式转换为强大的符号计算对象,为工程计算和几何建模提供了坚实的基础设施。其设计平衡了灵活性、性能和可扩展性,是 OpenCASCADE 数学能力的关键组成部分。
4.ExprIntrp_GenExp
ExprIntrp_GenExp
是 OpenCASCADE 表达式解释器模块中专门用于生成数学表达式的核心类,继承自基础生成器类。以下是对其源码的详细解析:
4.1.类定义与继承关系
头文件位置
ExprIntrp_GenExp.hxx
类声明
class ExprIntrp_GenExp : public ExprIntrp_Generator {
DEFINE_STANDARD_RTTIEXT(ExprIntrp_GenExp, ExprIntrp_Generator)
public:
// 创建实例的工厂方法
Standard_EXPORT static Handle(ExprIntrp_GenExp) Create();
// 获取解析后的表达式
Standard_EXPORT Handle(Expr_GeneralExpression) Expression() const;
protected:
// 构造函数(保护,只能通过Create使用)
Standard_EXPORT ExprIntrp_GenExp();
// 设置结果(供语法分析器回调)
Standard_EXPORT void SetResult(const Handle(Expr_GeneralExpression)& exp) Standard_OVERRIDE;
private:
Handle(Expr_GeneralExpression) myExpression; // 存储解析结果
};
继承关系
Standard_Transient (OCCT基类)
↑
ExprIntrp_Generator (基础生成器)
↑
ExprIntrp_GenExp (表达式生成器)
4.2.核心功能解析
4.2.1. 构造函数
ExprIntrp_GenExp::ExprIntrp_GenExp() : myExpression(nullptr) {
// 初始化父类
ExprIntrp_Generator::Use(new ExprIntrp_yacc(this));
}
- 保护访问:只能通过
Create()
方法实例化 - 初始化:自动创建关联的语法分析器
- 状态设置:结果表达式初始化为空
4.2.2. 工厂方法
Handle(ExprIntrp_GenExp) ExprIntrp_GenExp::Create() {
return new ExprIntrp_GenExp();
}
- 遵循OCCT对象创建规范
- 返回智能指针管理的实例
4.2.3. 结果设置方法
void ExprIntrp_GenExp::SetResult(const Handle(Expr_GeneralExpression)& exp) {
myExpression = exp;
}
- 语法分析器回调:在解析完成后被语法分析器调用
- 结果存储:保存最终生成的表达式树
- 覆盖基类:实现基类的纯虚函数
4.2.4. 结果获取方法
Handle(Expr_GeneralExpression) ExprIntrp_GenExp::Expression() const {
return myExpression;
}
- 返回解析得到的表达式树
- 调用前需确保
Process()
已成功执行
4.3.与基类的关键差异
4.3.1. 结果类型特定化
特性 | ExprIntrp_Generator (基类) |
ExprIntrp_GenExp (派生类) |
---|---|---|
结果类型 | 通用(表达式或关系) | 仅表达式 |
结果获取方法 | GetResult()/GetRelation() |
Expression() |
使用场景 | 通用解析 | 纯数学表达式解析4. |
4.3.2. 简化的接口
// 使用GenExp的简化流程
Handle(ExprIntrp_GenExp) gen = ExprIntrp_GenExp::Create();
gen->Process("x^2 + sin(y)");
Handle(Expr_GeneralExpression) expr = gen->Expression();
// 对比基础Generator
Handle(ExprIntrp_Generator) baseGen = ExprIntrp_Generator::Create();
baseGen->Process("x^2 + sin(y)");
Handle(Expr_GeneralExpression) expr = baseGen->GetResult(); // 需要类型判断
4.3.3. 自动化的分析器关联
// 基类需要手动关联分析器
baseGen->Use(new ExprIntrp_yacc(baseGen));
// GenExp在构造函数中自动关联
ExprIntrp_GenExp::ExprIntrp_GenExp() {
Use(new ExprIntrp_yacc(this)); // 自动完成
}
4.4.工作流程
典型使用序列
错误处理流程
4.5.关键扩展点
4.5.1. 自定义表达式构建
class CustomGenExp : public ExprIntrp_GenExp {
protected:
void SetResult(const Handle(Expr_GeneralExpression)& exp) override {
// 添加自定义转换
Handle(Expr_GeneralExpression) processed = ProcessExpression(exp);
myExpression = processed;
}
private:
Handle(Expr_GeneralExpression) ProcessExpression(const Handle(Expr_GeneralExpression)& input) {
// 示例:自动转换为双精度计算
return new Expr_DoublePrecision(input);
}
};
4.5.2. 语法分析器覆盖
class CustomGenExp : public ExprIntrp_GenExp {
protected:
ExprIntrp_GenExp() {
// 替换为自定义分析器
Use(new CustomExpressionParser(this));
}
};
class CustomExpressionParser : public ExprIntrp_yacc {
public:
CustomExpressionParser(ExprIntrp_GenExp* gen)
: ExprIntrp_yacc(gen) {}
int parse() override {
// 自定义解析逻辑
...
}
};
4.5.3. 预解析钩子
class CustomGenExp : public ExprIntrp_GenExp {
public:
void Process(const TCollection_AsciiString& str) override {
// 预处理器:替换简写语法
TCollection_AsciiString processed = Preprocess(str);
ExprIntrp_GenExp::Process(processed);
}
private:
TCollection_AsciiString Preprocess(const TCollection_AsciiString& input) {
// 示例:将 ** 替换为 ^
return input.ReplaceAll("**", "^");
}
};
4.6.优化策略
4.6.1. 表达式缓存
class CachedGenExp : public ExprIntrp_GenExp {
public:
void Process(const TCollection_AsciiString& str) override {
if (myCache.IsBound(str)) {
myExpression = myCache(str);
return;
}
ExprIntrp_GenExp::Process(str);
myCache.Bind(str, myExpression);
}
private:
NCollection_DataMap<TCollection_AsciiString, Handle(Expr_GeneralExpression)> myCache;
};
4.6.2. 并行解析支持
class ThreadSafeGenExp : public ExprIntrp_GenExp {
public:
void Process(const TCollection_AsciiString& str) override {
std::lock_guard<std::mutex> lock(myMutex);
ExprIntrp_GenExp::Process(str);
}
private:
std::mutex myMutex;
};
4.6.3. 增量解析
class IncrementalGenExp : public ExprIntrp_GenExp {
public:
void Start() {
myParser->Start();
}
void Append(const TCollection_AsciiString& partial) {
myLexer->AppendInput(partial);
if (myParser->CanContinue()) {
myParser->Resume();
}
}
void Finish() {
myParser->Finish();
}
};
4.7.典型应用场景
CAD 参数化建模
// 创建参数化圆柱体半径表达式
Handle(ExprIntrp_GenExp) radiusGen = ExprIntrp_GenExp::Create();
radiusGen->DefineVariable("base");
radiusGen->DefineVariable("t");
radiusGen->Process("base + t * 0.1");
// 在循环中使用
for (double t = 0; t <= 1.0; t += 0.1) {
double radius = radiusGen->Expression()->Evaluate({{"base", 5.0}, {"t", t}});
createCylinder(radius, height);
}
工程计算模板
// 创建应力计算表达式
Handle(ExprIntrp_GenExp) stressGen = ExprIntrp_GenExp::Create();
stressGen->DefineFunction("sqrt", 1);
stressGen->Process("sqrt(Fx^2 + Fy^2) / A");
// 批量计算
for (const auto& forceData : forceDataset) {
double stress = stressGen->Expression()->Evaluate({
{"Fx", forceData.Fx},
{"Fy", forceData.Fy},
{"A", area}
});
results.push_back(stress);
}
动态函数绘图
// 用户输入的函数表达式
Handle(ExprIntrp_GenExp) funcGen = ExprIntrp_GenExp::Create();
funcGen->DefineFunction("sin", 1);
funcGen->DefineFunction("cos", 1);
funcGen->Process(userInput); // 例如 "sin(x)*cos(2*x)"
// 生成点集
std::vector<gp_Pnt> points;
for (double x = 0; x <= 6.28; x += 0.1) {
double y = funcGen->Expression()->Evaluate({{"x", x}});
points.push_back(gp_Pnt(x, y, 0));
}
// 创建曲线
createBSplineCurve(points);
4.8.性能分析
4.8.1. 解析阶段性能
操作 | 时间复杂度 | 优化建议 |
---|---|---|
词法分析 | O(n) | 使用DFA优化正则匹配 |
语法分析 | O(n) | 使用LALR(1)解析器 |
符号查找 | O(1) | 哈希表优化 |
表达式树构建 | O(n) | 对象池减少内存分配 |
4.8.2. 求值阶段性能
表达式类型 | 求值开销 | 优化策略 |
---|---|---|
简单表达式 | ~100ns | 直接计算 |
深层嵌套表达式 | ~10μs | 表达式扁平化 |
含变量表达式 | ~1μs | 预编译为字节码 |
含函数调用 | ~10μs | 内联小函数 |
4.8.3. 内存使用优化
// 轻量级表达式节点
class LightweightExpression : public Expr_GeneralExpression {
// 最小化内存占用
// 使用flyweight模式共享相同子表达式
};
// 在生成器中配置
void ExprIntrp_GenExp::SetResult(const Handle(Expr_GeneralExpression)& exp) {
// 应用轻量化转换
myExpression = Lightweightizer::Convert(exp);
}
4.9.扩展应用:单位系统集成
带单位的表达式
class UnitAwareGenExp : public ExprIntrp_GenExp {
public:
void Process(const TCollection_AsciiString& str) override {
// 分离单位和表达式
auto [exprStr, unitStr] = SplitUnit(str);
// 解析表达式
ExprIntrp_GenExp::Process(exprStr);
// 附加单位
myUnit = ParseUnit(unitStr);
}
Handle(Expr_GeneralExpression) ExpressionWithUnit() const {
return new Expr_WithUnit(myExpression, myUnit);
}
private:
Handle(UnitSystem_Unit) myUnit;
};
使用示例
UnitAwareGenExp gen;
gen.Process("F/m^2 [N/m^2]"); // 帕斯卡压力单位
Handle(Expr_GeneralExpression) expr = gen.ExpressionWithUnit();
expr->Evaluate({{"F", 100}, {"m", 0.1}}); // 100/(0.1^2) = 10000 N/m²
4.10.总结
ExprIntrp_GenExp
是 OpenCASCADE 中专注于数学表达式生成的专业工具:
- 核心定位:
- 数学表达式解析的专业化实现
- 简化表达式获取接口
- 自动化分析器配置
- 关键优势:
扩展能力:
- 自定义表达式后处理
- 语法分析器覆盖
- 预处理钩子
- 单位系统集成
性能优化:
- 表达式缓存
- 线程安全支持
- 增量解析
- 轻量化表达式树
应用场景:
- CAD 参数化设计
- 工程计算模板
- 动态函数可视化
- 科学计算集成
最佳实践:
// 推荐使用模式 Handle(ExprIntrp_GenExp) gen = ExprIntrp_GenExp::Create(); gen->DefineVariables({"x","y","z"}); gen->DefineStandardFunctions(); // 内置数学函数 if (gen->Parse("sqrt(x^2 + y^2 + z^2)")) { auto expr = gen->Expression(); double norm = expr->Evaluate({{"x",3},{"y",4},{"z",12}}); // 13 }
作为 OpenCASCADE 表达式处理体系的关键组件,ExprIntrp_GenExp
为数学表达式处理提供了高效、专业的解决方案,特别适合需要精确数学计算的工程和科学应用场景。
5.ExprIntrp_GenFct
ExprIntrp_GenFct
是 OpenCASCADE 表达式解释器模块中专门用于解析和生成函数定义的核心类,继承自基础生成器类。以下是对其源码的详细解析:
5.1.类定义与继承关系
头文件位置
ExprIntrp_GenFct.hxx
类声明
class ExprIntrp_GenFct : public ExprIntrp_Generator {
DEFINE_STANDARD_RTTIEXT(ExprIntrp_GenFct, ExprIntrp_Generator)
public:
// 创建实例的工厂方法
Standard_EXPORT static Handle(ExprIntrp_GenFct) Create();
// 获取解析后的函数定义
Standard_EXPORT Handle(Expr_GeneralFunction) Function() const;
// 获取函数参数列表
Standard_EXPORT const ExprIntrp_SequenceOfNamedFunction& Parameters() const;
protected:
// 构造函数(保护,只能通过Create使用)
Standard_EXPORT ExprIntrp_GenFct();
// 设置结果(供语法分析器回调)
Standard_EXPORT void SetResult(const Handle(Expr_GeneralExpression)& exp) Standard_OVERRIDE;
// 处理函数定义
Standard_EXPORT void DefineFunction(const TCollection_AsciiString& name, const ExprIntrp_SequenceOfNamedFunction& params, const Handle(Expr_GeneralExpression)& body);
private:
Handle(Expr_GeneralFunction) myFunction; // 存储解析结果
ExprIntrp_SequenceOfNamedFunction myParameters; // 函数参数列表
};
5.2.核心功能解析
5.2.1. 构造函数
ExprIntrp_GenFct::ExprIntrp_GenFct() : myFunction(nullptr) {
// 初始化父类
ExprIntrp_Generator::Use(new ExprIntrp_FctParser(this));
// 注册函数定义关键字
RegisterKeyword("function");
RegisterKeyword("endfunction");
}
- 保护访问:只能通过
Create()
方法实例化 - 专用分析器:使用
ExprIntrp_FctParser
替代通用语法分析器 - 关键字注册:添加函数定义专用关键字
5.2.2. 函数定义处理
void ExprIntrp_GenFct::DefineFunction(const TCollection_AsciiString& name, const ExprIntrp_SequenceOfNamedFunction& params, const Handle(Expr_GeneralExpression)& body) {
// 创建函数对象
myFunction = new Expr_UserDefinedFunction(name, params, body);
// 存储参数列表
myParameters = params;
}
- 参数管理:存储函数参数序列
- 函数创建:生成用户定义函数对象
- 表达式封装:将函数体封装为可执行单元
5.2.3. 语法分析器扩展
class ExprIntrp_FctParser : public ExprIntrp_yacc {
public:
// 函数定义语法规则
function_decl: TKN_FUNCTION TKN_IDENTIFIER '(' param_list ')' expression TKN_ENDFUNCTION {
generator->DefineFunction($2, $4, $6);
}
param_list: /* 空 */
| identifier_list
;
identifier_list: TKN_IDENTIFIER
| identifier_list ',' TKN_IDENTIFIER
;
};
- 专用语法:添加函数定义语法规则
- 参数解析:支持逗号分隔的参数列表
- 作用域管理:函数体在
function...endfunction
之间
5.3.关键特性
5.3.1. 函数定义语法
<函数定义> ::= "function" <函数名> "(" [<参数列表>] ")" <表达式> "endfunction"
<参数列表> ::= <标识符> | <标识符> "," <参数列表>
5.3.2. 参数处理机制
// 参数序列类型定义
typedef NCollection_Sequence<Handle(Expr_NamedFunction)> ExprIntrp_SequenceOfNamedFunction;
// 在分析器中收集参数
void ExprIntrp_FctParser::AddParameter(const TCollection_AsciiString& name) {
myCurrentParams.Append(new Expr_NamedFunction(name));
}
5.3.3. 作用域管理
class FunctionScope : public Standard_Transient {
public:
// 进入函数作用域
void EnterFunction(const TCollection_AsciiString& name) {
myScopeStack.Push(name);
myLocalVars.Clear();
}
// 退出函数作用域
void ExitFunction() {
if (!myScopeStack.IsEmpty()) {
myScopeStack.Pop();
}
}
// 添加局部变量
void AddLocalVar(const TCollection_AsciiString& name) {
myLocalVars.Append(name);
}
// 检查是否为局部变量
Standard_Boolean IsLocalVar(const TCollection_AsciiString& name) const {
return myLocalVars.Contains(name);
}
private:
NCollection_Stack<TCollection_AsciiString> myScopeStack;
NCollection_List<TCollection_AsciiString> myLocalVars;
};
5.4.工作流程
函数解析过程
5.5.功能扩展
5.5.1. 多行函数支持
class MultiLineGenFct : public ExprIntrp_GenFct {
protected:
void SetResult(const Handle(Expr_GeneralExpression)& exp) override {
// 合并多行表达式为块
if (!myExpressionBlock.IsEmpty()) {
myExpressionBlock.Append(exp);
myFunction = new Expr_UserDefinedFunction(myCurrentName, myParameters, new Expr_Block(myExpressionBlock));
}
}
void StartFunctionBody() {
myExpressionBlock.Clear();
}
void AddToFunctionBody(const Handle(Expr_GeneralExpression)& exp) {
myExpressionBlock.Append(exp);
}
private:
ExprIntrp_SequenceOfExpression myExpressionBlock;
};
5.5.2. 类型注解支持
class TypedGenFct : public ExprIntrp_GenFct {
public:
void DefineParameterType(const TCollection_AsciiString& param, const Handle(Expr_Type)& type) {
myParamTypes.Bind(param, type);
}
protected:
void DefineFunction(...) override {
// 创建带类型检查的函数
myFunction = new TypedUserFunction(name, params, body, myParamTypes);
}
private:
NCollection_DataMap<TCollection_AsciiString, Handle(Expr_Type)> myParamTypes;
};
5.5.3. 闭包支持
class ClosureGenFct : public ExprIntrp_GenFct {
public:
void SetClosureContext(const Handle(Expr_Scope)& context) {
myClosureContext = context;
}
protected:
void DefineFunction(...) override {
// 创建闭包(捕获上下文)
myFunction = new Expr_Closure(name, params, body, myClosureContext);
}
private:
Handle(Expr_Scope) myClosureContext;
};
5.6.使用示例
基本函数定义
// 创建函数生成器
Handle(ExprIntrp_GenFct) gen = ExprIntrp_GenFct::Create();
// 解析函数定义
gen->Process(R"(
function circle_area(r)
PI * r^2
endfunction
)");
// 获取函数对象
Handle(Expr_GeneralFunction) areaFunc = gen->Function();
// 使用函数
Handle(Expr_NamedUnknown) r = new Expr_NamedUnknown("r");
Handle(Expr_GeneralExpression) area = areaFunc->Call({r});
多参数函数
gen->Process(R"(
function distance3d(x1,y1,z1,x2,y2,z2)
sqrt((x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2)
endfunction
)");
// 获取参数列表
auto params = gen->Parameters(); // [x1,y1,z1,x2,y2,z2]
// 调用函数
double d = areaFunc->Evaluate({
{"x1", 0.0}, {"y1", 0.0}, {"z1", 0.0},
{"x2", 3.0}, {"y2", 4.0}, {"z2", 12.0}
}); // 13.0
函数库构建
// 创建函数库
NCollection_DataMap<TCollection_AsciiString, Handle(Expr_GeneralFunction)> functionLib;
// 解析多个函数
const char* functions[] = {
"function sqr(x) x^2 endfunction",
"function cube(x) x^3 endfunction",
"function hypot(a,b) sqrt(sqr(a)+sqr(b)) endfunction"
};
for (auto fdef : functions) {
gen->Process(fdef);
functionLib.Bind(gen->Function()->GetName(), gen->Function());
}
// 使用函数库
auto hypot = functionLib.Find("hypot");
double result = hypot->Evaluate({{"a",3.0},{"b",4.0}}); // 5.0
5.7.性能优化
5.7.1. 函数内联优化
class InliningGenFct : public ExprIntrp_GenFct {
protected:
void DefineFunction(...) override {
// 对小函数进行内联
if (body->ExpressionSize() < 5) {
myFunction = new InlinedFunction(name, params, body);
} else {
ExprIntrp_GenFct::DefineFunction(name, params, body);
}
}
};
5.7.2. 函数缓存
class CachedGenFct : public ExprIntrp_GenFct {
public:
void Process(const TCollection_AsciiString& str) override {
TCollection_AsciiString signature = ComputeSignature(str);
if (myCache.IsBound(signature)) {
myFunction = myCache(signature);
return;
}
ExprIntrp_GenFct::Process(str);
myCache.Bind(signature, myFunction);
}
private:
NCollection_DataMap<TCollection_AsciiString, Handle(Expr_GeneralFunction)> myCache;
};
5.7.3. 预编译函数
Handle(Expr_CompiledFunction) CompileFunction(const TCollection_AsciiString& fdef) {
Process(fdef);
return new Expr_CompiledFunction(myFunction);
}
// 使用编译后函数
auto compiledFunc = CompileFunction("function f(x) sin(x)+cos(x) endfunction");
double result = compiledFunc->Evaluate({{"x", M_PI/4}}); // ≈1.414
5.8.应用场景
CAD 参数化设计
// 定义几何关系函数
gen->Process(R"(
function cylinder_volume(r, h)
PI * r^2 * h
endfunction
)");
// 在模型中使用
TopoDS_Shape cylinder = createCylinder();
BRepBuilderAPI_MakeParameterized param(cylinder);
param.BindFunction("volume", gen->Function());
param.SetParameter("h", 10.0);
param.SetParameter("r", 5.0);
// 自动更新
param.SetParameter("r", 6.0);
Standard_Real vol = param.Evaluate("volume"); // PI*6²*10
工程约束系统
// 定义材料应力函数
gen->Process(R"(
function von_mises(s1, s2, s3)
sqrt(0.5*((s1-s2)^2 + (s2-s3)^2 + (s3-s1)^2))
endfunction
)");
// 在FEM分析中使用
FEM_Analysis analysis;
analysis.AddMaterialProperty("stress_criteria", gen->Function());
// 评估应力
double s1 = 100.0, s2 = 50.0, s3 = -20.0;
double vm = analysis.EvaluateProperty("stress_criteria", {{"s1",s1},{"s2",s2},{"s3",s3}});
动态公式编辑器
// 用户定义函数
void OnUserDefineFunction(const TCollection_AsciiString& fdef)
{
try {
myGenFct->Process(fdef);
auto func = myGenFct->Function();
// 添加到函数库
myFunctionLib.Add(func);
// 更新UI
UpdateFunctionList(func);
}
catch (ExprIntrp_SyntaxError& e) {
ShowError(e.Message());
}
}
// 使用用户函数
void OnApplyFunction() {
auto func = GetSelectedFunction();
auto params = GetParameterValues();
double result = func->Evaluate(params);
DisplayResult(result);
}
5.9.总结
ExprIntrp_GenFct
是 OpenCASCADE 中用于函数定义解析的专业工具:
- 核心定位:
- 函数定义语法的专业解析
- 用户定义函数的创建与管理
- 参数列表的精确处理
- 关键特性:
扩展能力:
- 多行函数支持
- 类型注解系统
- 闭包和上下文捕获
- 函数内联优化
性能优化:
- 函数缓存机制
- 预编译函数
- 小函数内联
应用场景:
- CAD 参数化设计
- 工程约束系统
- 动态公式编辑器
- 科学计算函数库
最佳实践:
// 创建函数生成器 Handle(ExprIntrp_GenFct) gen = ExprIntrp_GenFct::Create(); // 定义数学函数库 const char* mathFuncs[] = { "function sigmoid(x) 1.0/(1.0+exp(-x)) endfunction", "function relu(x) max(0,x) endfunction", "function tanh(x) (exp(x)-exp(-x))/(exp(x)+exp(-x)) endfunction" }; // 编译为高效函数 NCollection_DataMap<TCollection_AsciiString, Handle(Expr_CompiledFunction)> compiledLib; for (auto fdef : mathFuncs) { gen->Process(fdef); compiledLib.Bind(gen->Function()->GetName(), new Expr_CompiledFunction(gen->Function())); } // 使用优化后的函数 double s = compiledLib("sigmoid")->Evaluate({{"x", 2.0}}); // ≈0.88
作为 OpenCASCADE 函数处理体系的核心组件,ExprIntrp_GenFct
为动态函数定义和复杂数学建模提供了强大支持,特别适合需要高级数学表达能力的工程和科学应用场景。
6.ExprIntrp_GenRel
ExprIntrp_GenRel
是 OpenCASCADE 表达式解释器模块中专门用于解析和生成关系表达式的核心类,继承自基础生成器类。以下是对其源码的详细解析:
6.1.类定义与继承关系
头文件位置
ExprIntrp_GenRel.hxx
类声明
class ExprIntrp_GenRel : public ExprIntrp_Generator {
DEFINE_STANDARD_RTTIEXT(ExprIntrp_GenRel, ExprIntrp_Generator)
public:
// 创建实例的工厂方法
Standard_EXPORT static Handle(ExprIntrp_GenRel) Create();
// 获取解析后的关系表达式
Standard_EXPORT Handle(Expr_GeneralRelation) Relation() const;
// 获取关系表达式中的自由变量
Standard_EXPORT void GetFreeVariables(ExprIntrp_SequenceOfNamedFunction& vars) const;
protected:
// 构造函数(保护,只能通过Create使用)
Standard_EXPORT ExprIntrp_GenRel();
// 设置结果(供语法分析器回调)
Standard_EXPORT void SetResult(const Handle(Expr_GeneralExpression)& exp) Standard_OVERRIDE;
// 处理关系表达式
Standard_EXPORT void DefineRelation(const Handle(Expr_GeneralExpression)& left, const Handle(Expr_GeneralExpression)& right, Expr_RelationType relType);
private:
Handle(Expr_GeneralRelation) myRelation; // 存储解析结果
ExprIntrp_SequenceOfNamedFunction myFreeVars; // 自由变量列表
};
6.2.核心功能解析
6.2.1. 构造函数
ExprIntrp_GenRel::ExprIntrp_GenRel() : myRelation(nullptr) {
// 初始化父类
ExprIntrp_Generator::Use(new ExprIntrp_RelParser(this));
// 注册关系运算符
RegisterOperator("=", Expr_Equal);
RegisterOperator(">", Expr_Greater);
RegisterOperator("<", Expr_Less);
RegisterOperator(">=", Expr_GreaterEqual);
RegisterOperator("<=", Expr_LessEqual);
RegisterOperator("<>", Expr_NotEqual);
}
- 保护访问:只能通过
Create()
方法实例化 - 专用分析器:使用
ExprIntrp_RelParser
关系表达式分析器 - 运算符注册:添加关系运算符及其类型映射
6.2.2. 关系表达式处理
void ExprIntrp_GenRel::DefineRelation(const Handle(Expr_GeneralExpression)& left, const Handle(Expr_GeneralExpression)& right, Expr_RelationType relType) {
// 根据关系类型创建相应关系对象
switch (relType) {
case Expr_Equal:
myRelation = new Expr_SingleRelation(left, right, Expr_Equal);
break;
case Expr_Greater:
myRelation = new Expr_SingleRelation(left, right, Expr_Greater);
break;
// 其他关系类型处理...
}
// 提取自由变量
ExtractFreeVariables(left);
ExtractFreeVariables(right);
}
void ExtractFreeVariables(const Handle(Expr_GeneralExpression)& exp) {
// 使用迭代器遍历表达式中的变量
Expr_UnknownIterator iter(exp);
while (iter.More()) {
Handle(Expr_NamedUnknown) var = iter.Value();
if (!myFreeVars.Contains(var)) {
myFreeVars.Append(var);
}
iter.Next();
}
}
6.2.3. 语法分析器扩展
class ExprIntrp_RelParser : public ExprIntrp_yacc {
public:
// 关系表达式语法规则
relation: expression rel_operator expression
{
generator->DefineRelation($1, $3, GetRelType($2));
}
rel_operator: TKN_EQUAL { $$ = Expr_Equal; }
| TKN_GREATER { $$ = Expr_Greater; }
| TKN_LESS { $$ = Expr_Less; }
| TKN_GREATER_EQUAL { $$ = Expr_GreaterEqual; }
| TKN_LESS_EQUAL { $$ = Expr_LessEqual; }
| TKN_NOT_EQUAL { $$ = Expr_NotEqual; }
;
};
6.3.关键特性
6.3.1. 支持的关系类型
运算符 | 关系类型 | 数学表示 |
---|---|---|
= |
Expr_Equal |
left = right |
> |
Expr_Greater |
left > right |
< |
Expr_Less |
left < right |
>= |
Expr_GreaterEqual |
left ≥ right |
<= |
Expr_LessEqual |
left ≤ right |
<> |
Expr_NotEqual |
left ≠ right |
6.3.2. 关系表达式结构
class Expr_SingleRelation : public Expr_GeneralRelation
{
public:
Expr_SingleRelation(const Handle(Expr_GeneralExpression)& left, const Handle(Expr_GeneralExpression)& right, Expr_RelationType type);
// 检查关系是否满足
Standard_Boolean IsSatisfied() const override;
// 简化关系
Handle(Expr_GeneralRelation) Simplified() const override;
// 求关系对变量的导数
Handle(Expr_GeneralRelation) Derivative(const Handle(Expr_NamedUnknown)& X) const override;
private:
Handle(Expr_GeneralExpression) myLeft;
Handle(Expr_GeneralExpression) myRight;
Expr_RelationType myType;
};
6.3.3. 自由变量分析
- 自动提取:解析时自动识别关系中的所有自由变量
- 去重存储:保证变量列表唯一性
- 应用场景:
- 约束求解前的变量准备
- 关系依赖分析
- 求解器配置
6.4.工作流程
关系表达式解析过程
6.5.功能扩展
6.5.1. 复合关系支持
class CompositeGenRel : public ExprIntrp_GenRel {
protected:
void DefineRelation(...) override {
// 支持逻辑组合:AND, OR
if (myCurrentRelation.IsNull()) {
ExprIntrp_GenRel::DefineRelation(left, right, relType);
} else {
Handle(Expr_GeneralRelation) newRel = new Expr_SingleRelation(left, right, relType);
if (myLastLogicalOp == "AND") {
myCurrentRelation = new Expr_Conjunction(myCurrentRelation, newRel);
} else if (myLastLogicalOp == "OR") {
myCurrentRelation = new Expr_Disjunction(myCurrentRelation, newRel);
}
}
}
void SetLogicalOperator(const TCollection_AsciiString& op) {
myLastLogicalOp = op;
}
private:
Handle(Expr_GeneralRelation) myCurrentRelation;
TCollection_AsciiString myLastLogicalOp;
};
6.5.2. 不等式链支持
class ChainedGenRel : public ExprIntrp_GenRel {
protected:
void ProcessChain(const Handle(Expr_GeneralExpression)& first, const ExprIntrp_SequenceOfRelation& chain) {
Handle(Expr_GeneralRelation) result;
for (Standard_Integer i = 1; i <= chain.Length(); i++) {
auto link = chain.Value(i);
Handle(Expr_GeneralRelation) rel = new Expr_SingleRelation((i == 1) ? first : chain.Value(i-1).Right(), link.Left(), Expr_Less); // 默认链式关系为小于
if (result.IsNull()) {
result = rel;
} else {
result = new Expr_Conjunction(result, rel);
}
}
myRelation = result;
}
};
6.5.3. 带公差的关系
class TolerantGenRel : public ExprIntrp_GenRel {
protected:
void DefineRelation(...) override {
// 创建带公差的关系
myRelation = new Expr_TolerantRelation(left, right, relType, myTolerance);
}
void SetTolerance(Standard_Real tol) {
myTolerance = tol;
}
private:
Standard_Real myTolerance;
};
class Expr_TolerantRelation : public Expr_SingleRelation {
public:
Standard_Boolean IsSatisfied() const override {
Standard_Real diff = myLeft->Evaluate() - myRight->Evaluate();
return Abs(diff) <= myTolerance;
}
};
6.6.使用示例
基本关系解析
// 创建关系生成器
Handle(ExprIntrp_GenRel) gen = ExprIntrp_GenRel::Create();
// 解析圆方程
gen->Process("x^2 + y^2 = 1");
// 获取关系对象
Handle(Expr_GeneralRelation) circleRel = gen->Relation();
// 获取自由变量
ExprIntrp_SequenceOfNamedFunction vars;
gen->GetFreeVariables(vars); // [x, y]
不等式系统
// 解析不等式系统
gen->Process(R"(
x + y > 5
AND
x - y < 3
AND
x >= 0
AND
y >= 0
)");
// 获取复合关系
Handle(Expr_Conjunction) system = Handle(Expr_Conjunction)::DownCast(gen->Relation());
// 求解可行域
Handle(Expr_Solver) solver = new Expr_Solver(system);
solver->Solve();
工程约束应用
// 机械臂位置约束
gen->Process(R"(
l1*cos(theta1) + l2*cos(theta1+theta2) = x
AND
l1*sin(theta1) + l2*sin(theta1+theta2) = y
AND
theta1 >= 0
AND
theta1 <= PI/2
)");
// 设置已知参数
solver->SetVariable("l1", 5.0);
solver->SetVariable("l2", 3.0);
solver->SetVariable("x", 4.0);
solver->SetVariable("y", 6.0);
// 求解角度
solver->Solve();
double theta1 = solver->GetValue("theta1");
double theta2 = solver->GetValue("theta2");
6.7.性能优化
6.7.1. 关系规范化
class NormalizedGenRel : public ExprIntrp_GenRel {
protected:
void DefineRelation(...) override {
// 规范化关系:将所有项移到左边
Handle(Expr_GeneralExpression) normalizedLeft = new Expr_Difference(left, right);
Handle(Expr_GeneralExpression) zero = new Expr_NumericValue(0.0);
// 创建标准形式:f(x) op 0
ExprIntrp_GenRel::DefineRelation(normalizedLeft, zero, relType);
}
};
6.7.2. 线性关系检测
class LinearGenRel : public ExprIntrp_GenRel {
protected:
void DefineRelation(...) override {
// 检测是否为线性关系
if (left->IsLinear() && right->IsLinear()) {
myRelation = new Expr_LinearRelation(left, right, relType);
} else {
ExprIntrp_GenRel::DefineRelation(left, right, relType);
}
}
};
class Expr_LinearRelation : public Expr_SingleRelation {
public:
// 线性关系的优化求解
Standard_Boolean IsSatisfied() const override {
// 使用线性代数方法求解
return SolveLinearSystem();
}
};
6.7.3. 关系预编译
Handle(Expr_CompiledRelation) CompileRelation(const TCollection_AsciiString& reldef) {
Process(reldef);
return new Expr_CompiledRelation(myRelation);
}
// 使用编译后关系
auto compiledRel = CompileRelation("x^2 + y^2 <= 1");
bool insideCircle = compiledRel->IsSatisfied({{"x",0.6},{"y",0.6}}); // true
6.8.应用场景
CAD 几何约束
// 点与曲线距离约束
gen->Process("distance(point, curve) = 0");
// 曲线相切约束
gen->Process("tangent(curve1, curve2) = true");
// 对称约束
gen->Process("symmetrical(point1, point2, plane) = true");
// 在参数化模型中应用
ParametricModel model;
model.AddConstraint(gen->Relation());
model.Solve();
结构工程分析
// 梁的弯曲约束
gen->Process(R"(
M/I = sigma/y
AND
sigma <= material_yield_stress
AND
deflection <= max_allowed_deflection
)");
// 在FEM分析中应用
FEM_StructuralAnalysis analysis;
analysis.AddConstraint(gen->Relation());
analysis.SetMaterial("steel");
analysis.Run();
机器人运动规划
// 机械臂运动学约束
gen->Process(R"(
end_effector_x = l1*cos(q1) + l2*cos(q1+q2)
AND
end_effector_y = l1*sin(q1) + l2*sin(q1+q2)
AND
q1_min <= q1 <= q1_max
AND
q2_min <= q2 <= q2_max
AND
path_obstacle_clearance >= min_clearance
)");
// 运动规划求解
RobotPathPlanner planner;
planner.SetConstraints(gen->Relation());
planner.PlanPath(startConfig, endConfig);
6.9.总结
ExprIntrp_GenRel
是 OpenCASCADE 中用于关系表达式解析的专业工具:
- 核心定位:
- 关系表达式(等式、不等式)的专业解析
- 约束系统的创建与管理
- 自由变量的自动提取
- 关键特性:
扩展能力:
- 复合关系(AND/OR)支持
- 不等式链解析
- 带公差的近似关系
- 线性关系优化
性能优化:
- 关系规范化
- 线性关系检测
- 关系预编译
应用场景:
- CAD 几何约束求解
- 结构工程分析
- 机器人运动规划
- 优化问题建模
最佳实践:
// 创建关系生成器 Handle(ExprIntrp_GenRel) gen = ExprIntrp_GenRel::Create(); // 解析约束系统 gen->Process(R"( x + y + z = 100 AND 2*x - y >= 30 AND y + 3*z <= 150 AND x >= 0, y >= 0, z >= 0 )"); // 获取约束系统 Handle(Expr_SystemRelation) constraints = Handle(Expr_SystemRelation)::DownCast(gen->Relation()); // 优化求解 OptimizationSolver solver; solver.SetObjective("maximize", "x + 2*y + 3*z"); solver.SetConstraints(constraints); solver.Solve(); // 获取最优解 double x = solver.GetValue("x"); double y = solver.GetValue("y"); double z = solver.GetValue("z");
作为 OpenCASCADE 约束求解体系的核心组件,ExprIntrp_GenRel
为工程约束系统和优化问题提供了强大的建模能力,特别适合需要精确关系表达的工程和科学应用场景。