mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-01 10:26:12 +03:00
Macros ending on "DEB" are replaced by OCCT_DEBUG across OCCT code; new macros described in documentation. Macros starting with DEB are changed to start with "OCCT_DEBUG_". Some code cleaned.
282 lines
7.4 KiB
C++
282 lines
7.4 KiB
C++
// Created on: 1991-04-17
|
|
// Created by: Arnaud BOUZY
|
|
// Copyright (c) 1991-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#ifndef OCCT_DEBUG
|
|
#define No_Standard_RangeError
|
|
#define No_Standard_OutOfRange
|
|
#endif
|
|
|
|
#include <Expr_Product.ixx>
|
|
#include <TColStd_Array1OfInteger.hxx>
|
|
#include <Expr_Sum.hxx>
|
|
#include <Expr_UnaryMinus.hxx>
|
|
#include <Expr_NumericValue.hxx>
|
|
#include <Expr_Operators.hxx>
|
|
#include <Expr.hxx>
|
|
|
|
Expr_Product::Expr_Product (const Expr_SequenceOfGeneralExpression& exps)
|
|
{
|
|
Standard_Integer i;
|
|
Standard_Integer max = exps.Length();
|
|
for (i=1; i<= max; i++) {
|
|
AddOperand(exps(i));
|
|
}
|
|
}
|
|
|
|
Expr_Product::Expr_Product (const Handle(Expr_GeneralExpression)& exp1, const Handle(Expr_GeneralExpression)& exp2)
|
|
{
|
|
AddOperand(exp1);
|
|
AddOperand(exp2);
|
|
}
|
|
|
|
Handle(Expr_GeneralExpression) Expr_Product::Copy () const
|
|
{
|
|
Standard_Integer i;
|
|
Standard_Integer max = NbOperands();
|
|
Expr_SequenceOfGeneralExpression simps;
|
|
for (i=1; i<= max; i++) {
|
|
simps.Append(Expr::CopyShare(Operand(i)));
|
|
}
|
|
return new Expr_Product(simps);
|
|
}
|
|
|
|
Standard_Boolean Expr_Product::IsIdentical (const Handle(Expr_GeneralExpression)& Other) const
|
|
{
|
|
if (!Other->IsKind(STANDARD_TYPE(Expr_Product))) {
|
|
return Standard_False;
|
|
}
|
|
Handle(Expr_Product) me = this;
|
|
Handle(Expr_Product) POther = Handle(Expr_Product)::DownCast(Other);
|
|
Standard_Integer max = NbOperands();
|
|
if (POther->NbOperands() != max) {
|
|
return Standard_False;
|
|
}
|
|
Handle(Expr_GeneralExpression) myop;
|
|
Handle(Expr_GeneralExpression) hisop;
|
|
Standard_Integer i=1;
|
|
TColStd_Array1OfInteger tab(1,max);
|
|
for (Standard_Integer k=1; k<=max;k++) {
|
|
tab(k)=0;
|
|
}
|
|
Standard_Boolean ident = Standard_True;
|
|
while ((i<=max) && (ident)) {
|
|
Standard_Integer j=1;
|
|
Standard_Boolean found = Standard_False;
|
|
myop = Operand(i);
|
|
while ((j<=max) && (!found)) {
|
|
hisop = POther->Operand(j);
|
|
found = myop->IsIdentical(hisop);
|
|
if (found) {
|
|
found = (tab(j) == 0);
|
|
tab(j)=i;
|
|
}
|
|
j++;
|
|
}
|
|
ident = found;
|
|
i++;
|
|
}
|
|
return ident;
|
|
}
|
|
|
|
Standard_Boolean Expr_Product::IsLinear () const
|
|
{
|
|
Standard_Integer i;
|
|
Standard_Integer max = NbOperands();
|
|
Standard_Boolean lin = Standard_True;
|
|
Standard_Boolean res = Standard_True;
|
|
Handle(Expr_GeneralExpression) asimp;
|
|
for (i=1; (i <= max) && res ; i++) {
|
|
asimp = Operand(i);
|
|
if (asimp->IsKind(STANDARD_TYPE(Expr_NamedUnknown)) || asimp->ContainsUnknowns()) {
|
|
if (lin) {
|
|
lin = Standard_False;
|
|
if (!asimp->IsLinear()) {
|
|
res = Standard_False;
|
|
}
|
|
}
|
|
else {
|
|
res = Standard_False;
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
Handle(Expr_GeneralExpression) Expr_Product::Derivative (const Handle(Expr_NamedUnknown)& X) const
|
|
{
|
|
if (!Contains(X)) {
|
|
return new Expr_NumericValue(0.0);
|
|
}
|
|
Handle(Expr_GeneralExpression) firstop = Expr::CopyShare(Operand(1)); // U
|
|
Handle(Expr_GeneralExpression) tailop; // V
|
|
Standard_Integer nbop = NbOperands();
|
|
if (nbop == 2) {
|
|
tailop = Expr::CopyShare(Operand(2));
|
|
}
|
|
else {
|
|
Handle(Expr_Product) prodop = Expr::CopyShare(Operand(2))*Expr::CopyShare(Operand(3));
|
|
for (Standard_Integer i=4; i<= nbop; i++) {
|
|
prodop->AddOperand(Expr::CopyShare(Operand(i)));
|
|
}
|
|
tailop = prodop;
|
|
}
|
|
Handle(Expr_GeneralExpression) firstder = firstop->Derivative(X); // U'
|
|
Handle(Expr_GeneralExpression) tailder = tailop->Derivative(X); // V'
|
|
|
|
Handle(Expr_Product) firstmember = firstop * tailder; // U*V'
|
|
|
|
Handle(Expr_Product) secondmember = firstder * tailop; // U'*V
|
|
|
|
Handle(Expr_Sum) resu = firstmember->ShallowSimplified() + secondmember->ShallowSimplified();
|
|
// U*V' + U'*V
|
|
|
|
return resu->ShallowSimplified();
|
|
}
|
|
|
|
|
|
Handle(Expr_GeneralExpression) Expr_Product::ShallowSimplified () const
|
|
{
|
|
Standard_Integer i;
|
|
Standard_Integer max = NbOperands();
|
|
Handle(Expr_GeneralExpression) op;
|
|
Expr_SequenceOfGeneralExpression newops;
|
|
Standard_Real vals = 0.;
|
|
Standard_Integer nbvals = 0;
|
|
Standard_Boolean subprod = Standard_False;
|
|
for (i=1; (i<= max) && !subprod; i++) {
|
|
op = Operand(i);
|
|
subprod = op->IsKind(STANDARD_TYPE(Expr_Product));
|
|
}
|
|
if (subprod) {
|
|
Handle(Expr_GeneralExpression) other;
|
|
Handle(Expr_Product) prodop;
|
|
Standard_Integer nbsprodop;
|
|
for (i=1; i<= max; i++) {
|
|
op = Operand(i);
|
|
if (op->IsKind(STANDARD_TYPE(Expr_Product))) {
|
|
prodop = Handle(Expr_Product)::DownCast(op);
|
|
nbsprodop = prodop->NbOperands();
|
|
for (Standard_Integer j=1; j<= nbsprodop; j++) {
|
|
other = prodop->Operand(j);
|
|
newops.Append(other);
|
|
}
|
|
}
|
|
else {
|
|
newops.Append(op);
|
|
}
|
|
}
|
|
prodop = new Expr_Product(newops);
|
|
return prodop->ShallowSimplified();
|
|
}
|
|
|
|
Standard_Boolean noone = Standard_True;
|
|
for (i = 1; i <= max ; i++) {
|
|
op = Operand(i);
|
|
if (op->IsKind(STANDARD_TYPE(Expr_NumericValue))) {
|
|
// numeric operands are cumulated separetly
|
|
Handle(Expr_NumericValue) NVop = Handle(Expr_NumericValue)::DownCast(op);
|
|
if (nbvals == 0) {
|
|
noone = Standard_False;
|
|
vals = NVop->GetValue();
|
|
nbvals =1;
|
|
}
|
|
else {
|
|
nbvals++;
|
|
vals = vals * NVop->GetValue();
|
|
}
|
|
}
|
|
else {
|
|
newops.Append(op);
|
|
}
|
|
}
|
|
if (!noone) {
|
|
// numeric operands encountered
|
|
if (newops.IsEmpty()) { // result is only numericvalue (even zero)
|
|
// only numerics
|
|
return new Expr_NumericValue(vals);
|
|
}
|
|
if (vals != 0.0) {
|
|
if (vals == 1.0) {
|
|
if (newops.Length() == 1) {
|
|
return newops(1);
|
|
}
|
|
return new Expr_Product(newops);
|
|
}
|
|
if (vals == -1.0) {
|
|
Handle(Expr_GeneralExpression) thefact;
|
|
if (newops.Length() == 1) {
|
|
thefact = newops(1);
|
|
}
|
|
else {
|
|
thefact = new Expr_Product(newops);
|
|
}
|
|
return -(thefact);
|
|
}
|
|
if (nbvals == 1) {
|
|
Handle(Expr_Product) me = this;
|
|
return me;
|
|
}
|
|
Handle(Expr_NumericValue) thevals = new Expr_NumericValue(vals);
|
|
newops.Append(thevals); // non-zero value added
|
|
return new Expr_Product(newops);
|
|
}
|
|
else {
|
|
return new Expr_NumericValue(vals); // zero absorb
|
|
}
|
|
}
|
|
Handle(Expr_Product) me = this;
|
|
return me;
|
|
}
|
|
|
|
Standard_Real Expr_Product::Evaluate(const Expr_Array1OfNamedUnknown& vars, const TColStd_Array1OfReal& vals) const
|
|
{
|
|
Standard_Integer max = NbOperands();
|
|
Standard_Real res = 1.0;
|
|
for (Standard_Integer i=1;i<=max;i++) {
|
|
res = res * Operand(i)->Evaluate(vars,vals);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
TCollection_AsciiString Expr_Product::String() const
|
|
{
|
|
Handle(Expr_GeneralExpression) op;
|
|
Standard_Integer nbop = NbOperands();
|
|
op = Operand(1);
|
|
TCollection_AsciiString str;
|
|
if (op->NbSubExpressions() > 1) {
|
|
str = "(";
|
|
str += op->String();
|
|
str += ")";
|
|
}
|
|
else {
|
|
str = op->String();
|
|
}
|
|
for (Standard_Integer i=2; i<=nbop; i++) {
|
|
str += "*";
|
|
op = Operand(i);
|
|
if (op->NbSubExpressions() > 1) {
|
|
str += "(";
|
|
str += op->String();
|
|
str += ")";
|
|
}
|
|
else {
|
|
str += op->String();
|
|
}
|
|
}
|
|
return str;
|
|
}
|