#include <sstream>
#include <iomanip>
+#define MAX_PRECISION 12
#define PRECISION 5
#define TOLERANCE (1.e-6)
if (theAttrs.find(aThisIter->first) == theAttrs.end()) {
return "original model had no attribute '" + aThisIter->first + "'";
}
- if (theAttrs[aThisIter->first] != aThisIter->second) {
+ if (aThisIter->first == "__shape__") {
+ // Compare the shape dump
+ if (theAttrs[aThisIter->first] != aThisIter->second) {
+ return compareShape(theAttrs[aThisIter->first], aThisIter->second);
+ }
+ }
+ else if (theAttrs[aThisIter->first] != aThisIter->second) {
return "attribute '" + aThisIter->first + "' is different (original != current) '" +
theAttrs[aThisIter->first] + "' != '" + aThisIter->second + "'";
}
return "";
}
+std::string ModelHighAPI_FeatureStore::compareShape(const std::string &theOrig, const std::string &theCurrent)
+{
+ std::istringstream issOrig(theOrig), issCurr(theCurrent);
+ std::string strOrig, strCurr;
+
+ // Compare the topological information (as a single string)
+ bool bDifferent = (!std::getline(issOrig, strOrig) || !std::getline(issCurr, strCurr) || strOrig != strCurr);
+
+ if (!bDifferent) {
+ auto cmpDouble = [](double aOrig, double aCurr, double tol=1.e-5) {
+ return (fabs(aOrig) < tol ? fabs(aCurr) < tol : ((fabs(aOrig-aCurr) / fabs(aOrig)) < tol));
+ };
+ auto cmpPoint = [](double pOrig[], double pCurr[], double tol=1.e-4) {
+ return (sqrt((pOrig[0]-pCurr[0])*(pOrig[0]-pCurr[0]) + (pOrig[1]-pCurr[1])*(pOrig[1]-pCurr[1]) + (pOrig[2]-pCurr[2])*(pOrig[2]-pCurr[2])) < tol);
+ };
+
+ // Compare the physical properties (Volume, Area, Center of Mass as doubles with tolerance)
+ double volOrig{}, areaOrig{}, pntOrig[3]={0.,0.,0.};
+ double volCurr{}, areaCurr{}, pntCurr[3]={0.,0.,0.};
+ issOrig >> volOrig >> areaOrig >> pntOrig[0] >> pntOrig[1] >> pntOrig[2];
+ issCurr >> volCurr >> areaCurr >> pntCurr[0] >> pntCurr[1] >> pntCurr[2];
+ bDifferent = (!cmpDouble(volOrig, volCurr) || !cmpDouble(areaOrig, areaCurr) || !cmpPoint(pntOrig, pntCurr));
+ }
+ if (bDifferent)
+ return "attribute '__shape__' is different (original != current) '" + theOrig + "' != '" + theCurrent + "'";
+
+ return "";
+}
+
static void dumpArray(std::ostringstream& theOutput, const double theArray[],
int theSize, int thePrecision = PRECISION)
{
std::string aTypeStr = anExp.current()->shapeTypeStr();
int aCount = 0;
for (; anExp.more(); anExp.next()) aCount++;
- aResult << aTypeStr.c_str() << ": " << aCount << std::endl;
+ aResult << aCount << " ";
+ }
+ else
+ {
+ aResult << "0 ";
}
}
+ aResult << "\n";
// output the main characteristics
double aVolume = GeomAlgoAPI_ShapeTools::volume(theShape);
if (aVolume > 1.e-5) {
- aResult<<"Volume: ";
- // volumes of too huge shapes write in the scientific format
- if (aVolume >= 1.e5)
- aResult<<std::scientific<<std::setprecision(7);
- else
- aResult<<std::fixed<<std::setprecision(3);
- aResult<<aVolume<<std::endl;
+ aResult << std::fixed << std::setprecision(MAX_PRECISION) << aVolume << " ";
}
+ else
+ aResult << "0.0 ";
double anArea = GeomAlgoAPI_ShapeTools::area(theShape);
- if (anArea > 1.e-5) {
- aResult << "Area: ";
- // volumes of too huge shapes write in the scientific format
- if (anArea >= 1.e5)
- aResult << std::scientific << std::setprecision(7);
- else
- aResult << std::fixed << std::setprecision(3);
- aResult << anArea << std::endl;
- }
+ if (anArea > 1.e-5)
+ aResult << std::fixed << std::setprecision(MAX_PRECISION) << anArea << " ";
+ else
+ aResult << "0.0 ";
std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
- aResult<<"Center of mass: ";
- double aCenterVals[3] = {aCenter->x(), aCenter->y(), aCenter->z()};
- dumpArray(aResult, aCenterVals, 3, 5);
- aResult<<std::endl;
+ aResult << std::fixed << std::setprecision(MAX_PRECISION) << aCenter->x() << " " << aCenter->y() << " " << aCenter->z() << std::endl;
return aResult.str();
}
/// returns not empty string with error if something is different
std::string compareData(std::shared_ptr<ModelAPI_Data> theData,
std::map<std::string, std::string>& theAttrs);
+ /// compares the main characteristics of a shape
+ /// returns not empty string with error if something is different
+ std::string compareShape(const std::string &theOrig,
+ const std::string &theCurrent);
/// dumps the attribute content to the string
std::string dumpAttr(const AttributePtr& theAttr);
- /// dumps the shape main charatceristics to string
+ /// dumps the shape main characteristics to string
std::string dumpShape(std::shared_ptr<GeomAPI_Shape>& theShape);
};
model.testNbSubShapes(aPartFeature, GeomAPI_Shape.FACE, [115])
model.testNbSubShapes(aPartFeature, GeomAPI_Shape.EDGE, [890])
model.testNbSubShapes(aPartFeature, GeomAPI_Shape.VERTEX, [1780])
- model.testResultsVolumes(aPartFeature, [1311.87963636394])
+ model.testResultsVolumes(aPartFeature, [1311.87963636394], 6)
model.testResultsAreas(aPartFeature, [3765.24411189])
- assert(model.checkPythonDump())
+from ModelHighAPI import CHECK_NAMING
+assert(model.checkPythonDump(CHECK_NAMING))